Routing connection with nested menu in angular material fails - angular-material

Here, I am using angular material for designing application. I have created nested menu bar. Now i am trying to route each submenu option from menubar. For that i am using routerlink and routerActivateLink modules from RouterModule directive.
But routing is not proppogating as per the requirement.
here is my code for routing,
<mat-menu #adminmenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item><span>Account Maintenance</span></button>
<button mat-menu-item [matMenuTriggerFor]="room"><span>Room Maintenance</span></button>
<mat-menu #room="matMenu">
<button mat-menu-item routerLink='addroom' routerLinkActive='active'><span>Add Room</span></button>
<button mat-menu-item><span>View/Assigned Unclaimed Room</span></button>
<button mat-menu-item><span>Modify/Update Room</span></button>
<button mat-menu-item><span>Delete Room</span></button>
<button mat-menu-item><span>Recover Deleted Room</span></button>
</mat-menu>
<button mat-menu-item> </button>
</mat-menu>
Here is my app.module.ts file,
#NgModule({
declarations: [
AppComponent,
MyformComponent,
MenuComponent,
PageareaComponent,AddroomComponent
],
imports: [
BrowserModule, FormsModule, MatMenuModule, MatIconModule, MatCardModule, MatSidenavModule,
BrowserAnimationsModule, MatInputModule, MatButtonModule,
RouterModule.forRoot([ {path:'login',component:MyformComponent},
{path:'menu',component:MenuComponent},
{path:'addroom',component:AddroomComponent}])
],
providers: [],
bootstrap: [AppComponent]
})
Please suggest me solution how to create routing in this case.

Related

React Website gives blank page on IOS Safari

I created a single page website with React. While it works fine on Android and Windows devices, I get a white page error on IOS-based devices. I have tried many solutions.
I don't get console error for Safari (latest version) for Windows either.
Here for live : https://fitbodyclub.netlify.app/
It has many code you may look at it here : https://github.com/kececibora/FitBodyClub-Website
index.js:
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
package.json:
{
"name": "fitclub",
"homepage": "https://fitbodyclub.netlify.app/",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.3.0",
"#testing-library/user-event": "^13.5.0",
"framer-motion": "^6.3.15",
"number-counter": "^1.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-onclickoutside": "^6.12.2",
"react-scripts": "5.0.1",
"react-scroll": "^1.8.7",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
I tried :
1 - "start_url": ".", // in manifest.json
2 - delete iframe from files
3- "homepage": ".", // added to package.json
4- "start_url": "``https://fitbodyclub.netlify.app/``", // added in manifest.json
5-"start": "yarn run start:tw & sleep 1 && yarn run start:cra", // added in package.json
6- <iframe allow="fullscreen" // added allow to iframe
7-
I started to rebuild it. I found the file gives that problem :
// import Header from "./Header/Header";
import "./Hero.css";
import hero_image from "../assets/hero_image.png";
import hero_image_back from "../assets/hero_image_back.png";
import Heart from "../assets/heart.png";
import Calories from "../assets/calories.png";
const transition = { type: "spring", duration: 3 };
const mobile = window.innerWidth <= 768 ? true : false;
function Hero() {
return (
<div className="hero" id="home">
<div className="blur hero-blur"></div>
<div className="left-h">
{/* <Header /> */}
{/* slogan */}
<div className="slogan">
<div
initial={{ left: mobile ? "165px" : "238px" }}
whileInView={{ left: "8px" }}
transition={{ ...transition, type: "tween" }}
></div>
<span>Sporun Kalbi burada atıyor 💛💛</span>
</div>
{/* Büyük Slogan */}
<div className="hero-text">
<div>
<span className="bosluk-text">Hayalinizdeki </span>
<span>Vücuda</span>
</div>
<div>
<span>Kavuşma Zamanı</span>
</div>
<div>
<span>
Burada sizlere hayalinizdeki vücuda kavuşmanıza yardım ediyoruz.
Sen de yapabilirsin!
</span>
</div>
</div>
{/* Figürler */}
<div className="figures">
<div>
<span>+500</span>
<span>metrekare</span>
</div>
<div>
<span>+2500</span>
<span>Üyelik</span>
</div>
<div>
<span>+250</span>
<span>Ekipman</span>
</div>
</div>
{/*Butonlar */}
<div className="hero-buttons">
<button className="btn">Katıl Bize</button>
<button className="btn">Daha Fazlası</button>
</div>
</div>
<div className="right-h">
<button className="btn">Üye Girişi</button>
<div
initial={{ right: "-1rem" }}
whileInView={{ right: "4rem" }}
transition={transition}
className="heart-rate"
>
<img src={Heart} alt="" />
<span>Heart Rate</span>
<span>116bpm</span>
</div>
{/* Hero images */}
<img src={hero_image} alt="" className="hero-image" id="hero_image" />
<img
initial={{ right: "11rem" }}
whileInView={{ right: "20rem" }}
transition={transition}
src={hero_image_back}
alt=""
className="hero-image-back"
id="hero_image_back"
/>
{/* Kalori */}
<div
initial={{ right: "37rem" }}
whileInView={{ right: "28rem" }}
transition={transition}
className="calories"
>
<img src={Calories} alt="" />
<div>
<span>Kalori</span>
<span>220 kcal</span>
</div>
</div>
</div>
</div>
);
}
export default Hero;
I started to rebuild it. I found the file gives that problem :
Part by part i builded so, a css element mix-blend-mode causes problem.
.App{mix-blend-mode: overlay;}

How can i fix Error: formControlName must be used with a parent formGroup directive. - Angular ReactiveForms FormBuilder

I'm getting this error:
ERROR Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).
I have already import import { ReactiveFormsModule } from '#angular/forms'; in module.ts
this is the template .html:
<mat-step [stepControl]="bankFormGroup" label="Some label">
<form [formGroup]="bankFormGroup">
<mat-form-field>
<mat-label>Banco</mat-label>
<mat-select ngDefaultControl formControlName="bank">
<mat-option *ngFor="let bank of banks" value="{{bank.id}}">
{{bank.id}} - {{bank.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Agência</mat-label>
<input matInput formControlName="agency" placeholder="0001">
</mat-form-field>
<mat-form-field>
<mat-label>Número da Conta Corrente</mat-label>
<input matInput formControlName="account" placeholder="26262661">
</mat-form-field>
{...action form}
</form>
</mat-step>
this is the component.ts:
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
export class UploadComponent {
bankFormGroup: FormGroup = this._formBuilder.group({
bank: ['', Validators.required],
agency: ['', Validators.required],
account: ['', Validators.required]
});
banks: any[] = [
{ id: '001', name: 'Banco do Brasil S.A.' },
{ id: '237', name: 'Banco Bradesco S.A.' },
];
constructor(private _formBuilder: FormBuilder) { }
}
I've already see another issues similar in another pages, like https://stackoverflow.com/questions/43305975 . But still i'm not able to remove this issue.
i'm using:
"#angular/forms": "^11.0.0",
"#angular/core": "^11.0.0",
"#angular/material": "^11.0.3",
The error was in another form in same component. Another form without <form [formGroup]="FormGroupName"> parent..
Check if there is another form without a parent container with [formGroup]

Angular Event Emitting to change material theme

Please I want to change the theme of my app by selecting one of the colors showing the image.
I have the following components:
Header Component (path: 'src/app/shared/components/header')
Default Component (path: 'src/app/layouts/default')
The image below is the Default Component containing the Header Component.
header.component.html
<mat-toolbar color="primary">
<mat-toolbar-row>
<button mat-icon-button (click)="toggleSideBar()">
<mat-icon>menu</mat-icon>
</button>
<span>APP LOGO</span>
<div fxFlex fxLayout="row" fxLayoutAlign="flex-end">
<ul fxLayout="row" fxLayoutGap="20px">
<li>
<button mat-icon-button [matMenuTriggerFor]="theme">
<mat-icon>format_color_fill</mat-icon>
</button>
<mat-menu #theme="matMenu">
<div class="btn-wrapper">
<button mat-mini-fab class="btn btn-default" (click)="selectedTheme='default'"></button>
<button mat-mini-fab class="btn btn-purple" (click)="selectedTheme='purple'"></button>
<button mat-mini-fab class="btn btn-pink" (click)="selectedTheme='pink'"></button>
<button mat-mini-fab class="btn btn-deep-orange" (click)="selectedTheme='deep-orange'"></button>
</div>
</mat-menu>
</li>
<li>
<button mat-icon-button>
<mat-icon>settings</mat-icon>
</button>
</li>
<li>
<button mat-button [matMenuTriggerFor]="menu">
<mat-icon>person_outline</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>
<mat-icon>exit_to_app</mat-icon>
Sign out
</button>
</mat-menu>
</li>
</ul>
</div>
</mat-toolbar-row>
</mat-toolbar>
header.component.ts
import {Component, EventEmitter, OnInit, Output} from '#angular/core';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
#Output() toggleSideBarForMe: EventEmitter<any> = new EventEmitter();
#Output() selectedTheme: string;
constructor() { }
ngOnInit(): void {
}
toggleSideBar(){
this.toggleSideBarForMe.emit();
setTimeout(() => {
window.dispatchEvent(
new Event('resize')
);
}, 300);
}
}
default.component.html
<div [ngClass]="selectedTheme">
<app-header (toggleSideBarForMe)="toggle()"></app-header>
<mat-drawer-container>
<mat-drawer mode="side" [opened]="sideBarOpen">
<app-sidebar></app-sidebar>
</mat-drawer>
<mat-drawer-content>
<router-outlet></router-outlet>
</mat-drawer-content>
</mat-drawer-container>
<app-footer></app-footer>
</div>
default.component.ts
import {Component, OnInit} from '#angular/core';
#Component({
selector: 'app-default',
templateUrl: './default.component.html',
styleUrls: ['./default.component.scss']
})
export class DefaultComponent implements OnInit {
sideBarOpen = true;
constructor() {
}
ngOnInit(): void {
}
toggle(){
this.sideBarOpen = !this.sideBarOpen;
}
}
Here is my custom theme file: custom-theme.scss
#import '~#angular/material/theming';
// Plus imports for other components in your app.
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
#include mat-core();
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$my-app-primary: mat-palette($mat-indigo);
$my-app-accent: mat-palette($mat-pink);
// The warn palette is optional (defaults to red).
$my-app-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and #include the theme mixins for each component
// that you are using.
#include angular-material-theme($my-app-theme);
.alternate-teal-theme {
$teal-app-primary: mat-palette($mat-teal);
$teal-app-accent: mat-palette($mat-yellow);
// The warn palette is optional (defaults to red).
$teal-app-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$teal-app-theme: mat-light-theme($teal-app-primary, $teal-app-accent, $teal-app-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and #include the theme mixins for each component
// that you are using.
#include angular-material-theme($teal-app-theme);
}
.purple {
$purple-primary: mat-palette($mat-purple);
$purple-accent: mat-palette($mat-light-green);
$purple-theme: mat-light-theme($purple-primary, $purple-accent);
#include angular-material-theme($purple-theme);
}
.pink {
$pink-primary: mat-palette($mat-pink);
$pink-accent: mat-palette($mat-yellow);
$pink-theme: mat-light-theme($pink-primary, $pink-accent);
#include angular-material-theme($pink-theme);
}
.deep-orange {
$deep-orange-primary: mat-palette($mat-deep-orange);
$deep-orange-accent: mat-palette($mat-teal, A100);
$deep-orange-theme: mat-light-theme($deep-orange-primary, $deep-orange-accent);
#include angular-material-theme($deep-orange-theme);
}
Please how do I make the selected theme to take effect on the app?
The content of custom-theme.scss file should be passed or imported into your style.scss. So that the theme affects the complete application you must declare the class css of the same in a div that encloses the html content of your boostrap component. And the error that I notice in your code is that in the file header.component.ts the output of the selectedTheme is not emitting any event, you should declare it like this #Output() selectedTheme: EventEmitter<string> = new EventEmitter<string>();, Here I leave you a working example of everything I just explained: stackblitz

Navigating between components using side-nav in angular 7

I have sidenav setup in the home page of my angular application. I have also setup links to other components in the sidenav. Now I want the components to load in the same space when their links are clicked with the sidenav and toolbar not getting affected.
The HTML file of the home page with the sidenav and toolbar
<mat-toolbar>
<button (click)='sidenav.toggle()'><mat-icon style="color: white">menu</mat-icon></button>
<b style="font-size: 22px; color: white">Hello {{user}}</b>
<nav>
<ul>
<li><button (click)='logout()'><div style='font-size: 19px; color: white'> LOGOUT</div></button></li>
</ul>
</nav>
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav mode='side' [(opened)]='opened'>
<mat-nav-list style="margin-top: 50px">
<a mat-list-item routerLink="/dashboard" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>dashboard</mat-icon><span> </span>DASHBOARD</button></a>
<a mat-list-item routerLink="/visual" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>timeline</mat-icon><span> </span>VISUALISATION</button></a>
<a mat-list-item routerLink="/config" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>settings</mat-icon><span> </span>PROFILE</button></a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
</mat-sidenav-content>
</mat-sidenav-container>
I want to ensure that when I open this page for the first time, dashboard will be displayed, but when i click in visualisation or profile, the dashboard component should be replaced by the other clicked component in the same place whithout the need to reload the toolbar and sidenav components.
To ensure that the sidenav acts as a navigation bar first we will need to specify the tag inside the tag.
Then the second step is to specify the router links in the sidenav links. Ensure that the router links that they point to are specified as child routes of the main component. To specify them go to the app-routing.module.ts module and specify the routes which in the above case would be :
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { DashboardViewComponent } from './dashboard-view/dashboard-view.component';
import { VisualisationComponent } from './visualisation/visualisation.component';
import { ConfgaccountComponent } from './confgaccount/confgaccount.component';
const routes: Routes = [
{
path: 'dashboard', component: DashboardComponent, children: [
{ path: 'dash', component: DashboardViewComponent },
{ path: 'visual', component: VisualisationComponent },
{ path: 'config', component: ConfgaccountComponent },
]
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Now the next step would be to specify the tags inside the tags to ensure that the whenever the links in the sidenav are clicked they are routed to the proper child component and it is displayed in the correct place.
Also ensure that the routerLinks inside the tags are updated to the proper routes specified for the child components, as present in the app-routing.module.ts file.
The modified HTML code will be :
<mat-toolbar>
<button (click)='sidenav.toggle()'><mat-icon style="color: white">menu</mat-icon></button>
<b style="font-size: 22px; color: white">Hello {{user}}</b>
<nav>
<ul>
<li><button (click)='logout()'><div style='font-size: 19px; color: white'> LOGOUT</div></button></li>
</ul>
</nav>
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav mode='side' [(opened)]='opened'>
<mat-nav-list style="margin-top: 50px">
<a mat-list-item routerLink="/dashboard/dash" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>dashboard</mat-icon><span> </span>DASHBOARD</button></a>
<a mat-list-item routerLink="/dashboard/visual" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>timeline</mat-icon><span> </span>VISUALISATION</button></a>
<a mat-list-item routerLink="/dashboard/config" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>settings</mat-icon><span> </span>PROFILE</button></a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<main>
<router-outlet></router-outlet>
</main>
</mat-sidenav-content>
</mat-sidenav-container>
The next step is to create a navigation service to which the router and sidenav subscribe to to ensure the smooth routing to proper components whenever the links are clicked. The service needs to be injected into the constructor of the main dashboard component to ensure it's successful working.
The nav.service.ts file will have contents as specified :
import { Injectable, EventEmitter } from '#angular/core';
import { Event, NavigationEnd, Router } from '#angular/router';
import { BehaviorSubject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class NavService {
public appDrawer: any;
public currentUrl = new BehaviorSubject<string>(undefined);
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationEnd) {
this.currentUrl.next(event.urlAfterRedirects);
}
});
}
}
Finally test the successful working of the child components in the main dashboard component. The sidenav will successfully help in proper navigation among child components now.

mat-form-field must contain a MatFormFieldControl. even i added MatFormFieldModule

Here im new to Angular Material please help me why im getting Error. I was copied code from https://material.angular.io/components/form-field/examples
<div class="example-container">
<mat-form-field>
<input matInput placeholder="Input">
</mat-form-field>
<mat-form-field>
<textarea matInput placeholder="Textarea"></textarea>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Select">
<mat-option value="option">Option</mat-option>
</mat-select>
</mat-form-field>
</div>
This is the same code which i copied from that url
App.module.ts
import {MatFormFieldModule} from '#angular/material/form-field';
import {MatInputModule} from '#angular/material/input';
imports: [
MatFormFieldModule,MatInputModule]
Looks like you forgot about MatSelectModule:
import {MatFormFieldModule} from '#angular/material/form-field';
import {MatInputModule} from '#angular/material/input';
import {MatSelectModule} from '#angular/material/select';
...
imports: [MatFormFieldModule,MatInputModule,MatSelectModule]
Try Removing placeholder="Input" of input box.
It worked for me give it a try.
In case this helps, here is my app.module.ts for my app using material:
import {
MatFormFieldModule,
MatInputModule,
} from '#angular/material';
....
#NgModule({
imports: [
.....,
MatFormFieldModule,
MatInputModule,
.....,
],
.....
})
export class AppModule { }
import {MatInputModule} from '#angular/material';
#NgModule({
imports: [
MatInputModule
],
exports:[
MatInputModule
]
})
at app.module.ts file
Remove placeholder from input tag.
Instead of using placeholder you could use
<mat-label>.....</mat-label>
Here is code:
<mat-form-field appearance="outline">
<input matInput required />
<mat-label>Username</mat-label>
</mat-form-field>

Resources