Navigating between pages has become challenging due to issues with the navbar, sidebar,

I successfully developed 4 Angular components:

  • 1st component: menu
  • 2nd component: header
  • 3rd component: home
  • 4th component: login

The menu component features a sidebar/navbar created using Material UI. The login component consists of the login page. However, when running ng serve, both the menu and login components are displayed together. My goal is to have only the login component displayed on the initial page redirect. I have set up routing for the login component to appear on the first page, but it currently appears with the menu bar content as well, which can be seen in the image. In app.component.html, I have added

<app-menu></app-menu>
because after logging in, I want the other component data to display when clicking any button on the sidebar.

Below is the code for the menu bar and all the components:

<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 Code:

<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>

Code in app.component.html:

<app-menu></app-menu>

Routing configuration in 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 aim to have only the login page displayed when running ng serve, while ensuring that all buttons in the sidebar and navbar work correctly with the router link.

Answer №1

Regardless of the path you take, angular will consistently present the AppComponent as the main entry point of your application (if you examine your index.html file, you'll see that the app component is directly nested within the body, and this cannot be altered).

Furthermore, regardless of the route you follow, angular will substitute the occurrence of

<router-outlet></router-outlet>
with the appropriate object based on your app's routing configuration.

Hence, when your path leads to login, these are the 3 steps involved in generating your HTML:

  1. You first create your final HTML file using the app template app.component.html. This template includes a reference to your MenuComponent:

    <app-menu></app-menu>
    .

  2. You then generate HTML content based on the menu template menu.component.html. The resulting HTML content replaces

    <app-menu></app-menu>
    in your final HTML file. Within this content, there is another reference managed by your app's routing logic:
    <router-outlet></router-outlet>
    .

  3. As per your app's routing configuration, the path login corresponds to the LoginComponent. Therefore, you generate HTML content from the login template login.component.html. This generated content takes the place of

    <router-outlet></router-outlet>
    in your final HTML file.

In the end, the desired outcome is the login template nested inside the menu template which, in turn, is nested inside the app template.

Solution

The simplest way to display only the login template at the path /login in your current setup is to modify your AppComponent so that it directly includes your login component without the MenuComponent specifically for the /login path.

In your app.component.ts, define a variable to determine the current case:

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

In your app.component.html, utilize this variable to control the behavior:

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

(also, remove <body> from your login.component.html, as you are already within a body element since the login component is nested inside the app component which itself is nested within the body of the index.html)

Answer №2

For Exclusive Use

<router-outlet ></router-outlet>

should be placed in app-component.html only.

To display the menu on all pages except the login page, configure routing as follows:

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

The routing for the login page click should lead to 'menu/home'

Although recommended routing setup is provided below instead:

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

Implement a ROUTING GUARD (canactivate or canactivatechild) to verify user authentication status and direct them to designated PAGEs within your components. The routing guard will steer users towards the login page if not logged in.

Then, clicking on the login page route should go to 'home'

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Hover over to reveal the button after a delay

I'm struggling with implementing a feature in my Angular code that displays a delete button when hovering over a time segment for 2 seconds. Despite trying different approaches, I can't seem to make it work. .delete-button { display: none; ...

DuplicateModelError: Unable to duplicate model after it has been compiled, React.js, MongoDB, TypeScript

In the early stages of developing an application using Next.js, Mongoose, and Typescript, I encountered a persistent issue. Whenever I attempt to send a request through Postman after clicking save, it fails, displaying the error message: OverwriteModelErr ...

Incorporate any enum value into a Typescript interface

I'm working with a Typescript interface export interface MyInterface { valid: boolean; resourceType: MyEnum; message: string; } As well as an enum enum MyEnum { 'a', 'b', 'c' } Is there a way to allow the ...

Setting up Node on a Ubuntu system

Currently, I am in the process of installing Node.js to run my Angular2 program. However, I encountered an error during the installation: npm WARN npm npm does not support Node.js v0.10.25 npm WARN npm You should probably upgrade to a newer version of nod ...

Struggling with intricate generic type mapping of records in Typescript

Whew...spent an entire day on this. My brain is fried... I am developing a type-safe mapper function that determines which props are needed based on the mapping type and can predict the output types based on the ReturnType. However, it seems like each re ...

Steps to resolve the error message 'Argument of type 'number' is not assignable to parameter of type 'string | RegExp':

Is there a way to prevent users from using special symbols or having blank spaces without any characters in my form? I encountered an error when trying to implement this in my FormGroup Validator, which displayed the message 'Argument of type 'nu ...

What could be the reason for Typescript attempting to interpret files in the `./build` directory as input files?

After struggling for an hour on this issue, I am stuck. The variables outDir and rootDir are set. However, the problem arises when only src is included in include, TypeScript shows the configuration via showConfig, yet it's attempting to compile 4 fi ...

employing flush for lodash's throttle wrapper

When using TypeScript with JavaScript and Angular: I am trying to use the throttle decorator from lodash to limit an API call while a user is navigating around the page, ensuring that it fires before they leave the site. In my TypeScript constructor, I h ...

Strange compilation error encountered with ng-packagr due to Angular @Input inheritance

Encountering a perplexing error message in Angular 7 while working with @Input inheritance. The error message seems illogical because I have 1 mandatory @Input and 2 optional @Input, so things should align... Error: Directive MyComponent, Expected 2 argum ...

Material UI autocomplete is not detecting the options parameter as an array

I am currently working on implementing an autocomplete field that retrieves options from my component's state, which in turn fetches data from the backend. Here is a snippet of my component: export const Person: React.FC<PersonProps> = ({name, a ...

How do I define two mutations in a single component using TypeScript and react-apollo?

After exploring this GitHub issue, I have successfully implemented one mutation with Typescript. However, I have been unable to figure out how to use 2 mutations within the same component. Currently, there is only a single mutate() function available in t ...

Obtaining RouteParams in the loader function of RouteConfig can be achieved by following a

Is there a way to achieve the following setup: @RouteConfig([ { path: '/example/:name', name: 'Example', loader: (params: RouteParams) => { let name = params.get('name'); return _EXAM ...

Guide to employing Axios types in project declaration files

When working on my project's type declaration file, I encountered a dilemma with using Axios types as part of my own types. The issue lies in the fact that all declarations for Axios are exported from their official repository. I specifically need to ...

Navigating with the router on a different page

My appcomponent contains all the routes, and on the next page I have several links that are supposed to route to the same router outlet. How can I navigate when a link is clicked? I attempted using [routerLink]="['PersonInvolved']", but I encoun ...

Create a dynamically updating list using React's TypeScript rendering at regular intervals

My goal is to create a game where objects fall from the top of the screen, and when clicked, they disappear and increase the score. However, I am facing an issue where the items are not visible on the screen. I have implemented the use of setInterval to d ...

Typedi's constructor injection does not produce any defined output

I am utilizing typedi in a Node (express) project and I have encountered an issue related to injection within my service class. It seems that property injection works fine, but constructor injection does not. Here is an example where property injection wo ...

Uncover hidden mysteries within the object

I have a function that takes user input, but the argument type it receives is unknown. I need to make sure that... value is an object value contains a key named "a" function x(value: unknown){ if(value === null || typeof value !== 'obj ...

What is the best way to restrict the key of an object type to only be within a specific union in TypeScript?

I need to create a set of server types in a union like this: type Union = 'A' | 'B' | 'C'; After that, I want to define an object type where the keys are limited to only certain options from this Union: // Use only 'A&ap ...

A step-by-step guide on making a web API request to propublica.org using an Angular service

Currently, I am attempting to extract data from propublica.org's congress api using an Angular 8 service. Despite being new to making Http calls to an external web api, I am facing challenges in comprehending the documentation available at this link: ...

What is the process of declaring a method within a subclass and then retrieving it from a method within the parent class using Typescript?

I am currently working with this TypeScript code snippet: abstract class Base { static actions:Record<string,unknown> static getActions () { return this.actions } } class Sub extends Base { static actions = { bar:(bar:string ...