The problem of navbar and side bar and routing

36 views Asked by At

I have created 4 components in Angular:

  • 1st menu
  • second header
  • 3rd is home and
  • 4th is login component

In menu component I have created sidbarnvbar using Material UI, and in login component I have created login page. And when I am doing ng serve, my menucomponent is showing with login component but I want to just show log in component on first page when page redirect, I set routing for login and it's coming on first page but problem is that it's coming with menubar content you can see in picture. I have written <app-menu></app-menu> in app.component.html because I want after my log in when I click on sidebar any button the other component data should come.

Here is my menubar and all component code

<mat-toolbar color="primary">
    <button (click)="drawer.toggle()" mat-icon-button>
        <mat-icon>menu</mat-icon>
    </button>
    <span>Angular</span>
    <span class="example-spacer"></span>
    <button routerLink="header" mat-button>home</button>
    <button routerLink="sidebar" mat-button>About</button>
    <button mat-button>contact</button>
    <form class="d-flex">
        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-success" type="submit">Search</button>
    </form>
    
</mat-toolbar>

<mat-drawer-container autosize>
    <mat-drawer #drawer opened="true" mode="side" position="start">
    <mat-nav-list>
        <mat-list-item>
            <button routerLink="header" mat-button><mat-icon>home</mat-icon> Home</button>
        </mat-list-item>
        <mat-list-item>
            <button routerLink="home" mat-button><mat-icon>home</mat-icon> Pages</button>
        </mat-list-item>
        <mat-list-item>
            <button routerLink="" mat-button><mat-icon>explore</mat-icon> Table</button>
        </mat-list-item>
        <mat-list-item>
            <button  routerLink="#" mat-button><mat-icon>Layout</mat-icon> Layout</button>
        </mat-list-item>
        <mat-list-item>
            <button mat-button><mat-icon>settings</mat-icon> Settings</button>
        </mat-list-item>
        <mat-list-item>
            <button mat-button><mat-icon>help</mat-icon> Help</button>
        </mat-list-item>
    </mat-nav-list>
    </mat-drawer>
    <mat-drawer-content>
        <div style="text-align: center;min-height: 600px;">
          <router-outlet></router-outlet>
            </div>
    </mat-drawer-content>
</mat-drawer-container>

login component

<body>
    <form [formGroup] ="loginform1" (ngSubmit)="loginUser()">
        <div class="login-container">
            <h2 class="lg">Login Page</h2>
            <label>User Name</label>
            <input type="text" name="Uname" id="Uname"  placeholder="Username" formControlName="Uname">
            <span style="color: red;" *ngIf="Uname && Uname.invalid && Uname.touched" >this field is required.</span>
            <br><br>
            <label>Password</label>
            <input type="password" name="password" id="Pass"  placeholder="Password" formControlName="password">
            <span style="color: red;" *ngIf="password && password.invalid && password.touched" >this field is required.</span>
            <br>
            <a href="#" style="color: white;">Forgot Password</a><br><br>
            <button  class="bt" (click)="submit()" [disabled]="loginform1.invalid">Login</button> <br><br>
            <input type="checkbox" id="check">
            <span>Remember me</span><br>
            <button type="type" class="btn btn-primary" routerLink="/dashboard">Register</button>
            <br><br>
        </div>
    </form>
</body>

app.component.html

<app-menu></app-menu>

app.routing

{path:'dashboard', component:DashboardComponent},
{path:'header', component:Headers},
{path:'home', component:HomeComponent},
{path:'menu', component:MenuComponent},
{path:'login',component:LoginComponent},
{ path: '',   redirectTo: '/login', pathMatch: 'full' },

I want when I run ng serve only login page should come, and in sidebar and navbar all the button should work with router link.

2

There are 2 answers

0
gabylink On

Whatever your path is, angular will always display the AppComponent. It is the front door of your application (look at your index.html file, the app component is the direct child of the body, and you may not change it.).

And whatever your path is, angular will replace the occurrence of <router-outlet></router-outlet> with the good object according to your app routing.

So, in your case, when your path is login, these are the 3 steps of your HTML generation:

  1. You generate your final HTML file with the app template app.component.html. In this template there is a reference to your MenuComponent: <app-menu></app-menu>.

  2. You generate HTML lines with the menu template menu.component.html. These generated HTML lines will replace <app-menu></app-menu> in your final HTML file. Inside these lines, there is an other reference managed by your app routing: <router-outlet></router-outlet>.

  3. According to your app routing, the path login use the component LoginComponent. So you generate HTML lines with the login template login.component.html. These generated HTML lines will replace <router-outlet></router-outlet> in your final HTML file.

At the end, the expected result is the login template inside the menu template inside the app template.

Solution

The shortest way to have only the login template on path /login from your current code is to change your AppComponent to directly put your login component without the MenuComponent when you are on the path /login.

In app.component.ts, declare a variable which allow you to know in which case you are:

export class AppComponent {
  public isLoginPath: boolean = this.route.url === "/login";  
  constructor(private route: Router) { }
}

In your app.component.html, use this variable to choose the good behavior:

<app-menu *ngIf="!isLoginPath"></app-menu>
<router-outlet *ngIf="isLoginPath"></router-outlet>

(and remove <body> in your login.component.html, you are already encapsulated in a body element, because login component is inside app component which is inside the body of the index.html)

0
toTheBestOfMyKnowledge On

Use Only

<router-outlet ></router-outlet>

in app-component.html.

If you want menu to be shown on all pages except the login page. Setup routing like below.

{
 path:'menu', 
 component:MenuComponent,
 children:[ 
     {path:'dashboard', component:DashboardComponent},
     {path:'home', component:HomeComponent},
 ]
},
{path:'login',component:LoginComponent},
{ path: '',   redirectTo: '/login', pathMatch: 'full' },

login page routing click should be to 'menu/home'

But I would recommend below routing setup over this.

{ path: '',   redirectTo: '/home', pathMatch: 'full' },
{
 path:'', 
 component:MenuComponent,
 canActivateChild:[OurRouteGuard]
 children:[ 
     {path:'dashboard', component:DashboardComponent},
     {path:'home', component:HomeComponent},
 ]
},
{path:'login',component:LoginComponent},

Using a ROUTING GUARD (canactivate or canactivatechild) to check if the user is LOGGED IN and Redirect user to PAGEs Implemented in your other components. Routing guard will redirect user to login page if not logged in.

and then login page routing click should be to 'home'