Customizing templates in Angular for specific pages

I am new to Angular and currently working on building a frontend while learning how to use Angular. I have created a test app where I am integrating authentication using an API that I wrote. The authentication process is functioning well, but I am struggling to understand how to implement a specific functionality.

Most of the app's content is restricted behind authentication. The goal is that if a user tries to access any page without being logged in, they should be redirected to the login page. This aspect is working smoothly.

However, the login page requires a completely different layout. None of the design elements from the main design should be visible on the login page, not even the CSS classes used on the body tag.

What would be the best approach to solve this issue?

I attempted to use *ngIf in the app.component.html file, but it did not work as expected. Additionally, I am unsure about how to change the body class in index.html.

I hope this explanation is clear enough. Below, I have provided some source code. If more information is needed, please let me know.

app.component.html:

   <ng-container *ngIf="accountService.currentUser$ | async">
        <app-preloader></app-preloader>
        <app-nav></app-nav>
        <app-sidebar></app-sidebar>
    
        <!-- Content Wrapper. Contains page content -->
        <div class="content-wrapper">
            <!-- Content Header (Page header) -->
            <div class="content-header">
                <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                    <h1 class="m-0">Dashboard</h1>
                    </div><!-- /.col -->
                </div><!-- /.row -->
                </div><!-- /.container-fluid -->
            </div>
            <!-- /.content-header -->
    
            <!-- Main content -->
            <section class="content">
                <div class="container-fluid">
                    <router-outlet></router-outlet>    
                </div><!-- /.container-fluid -->
            </section>
            <!-- /.content -->
        </div>
        <app-footer></app-footer>
    </ng-container>
    
    <ng-container *ngIf="(accountService.currentUser$ | async) === null">
        <router-outlet></router-outlet>   
    </ng-container>

index.html:

  <!doctype html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Client</title>
      <base href="/">
      <!-- Google Font: Source Sans Pro -->
      <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
      <!-- Ionicons -->
      <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="icon" type="image/x-icon" href="favicon.ico">
    </head>
    
    <body class="hold-transition sidebar-mini layout-fixed">
      <app-root></app-root>
    </body>
    </html>

app.routing.module.ts:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainComponent } from './main/main.component';
import { LoginComponent } from './login/login.component';
import { UserComponent } from './user/user.component';
import { AuthGuard } from './_guards/auth.guard';

const routes: Routes = [
  {
    path: '',
    runGuardsAndResolvers: 'always',
    canActivate: [AuthGuard],
    children: [
      {path: '', component: MainComponent},
      {path: 'user', component: UserComponent}
    ]
  },
  {path: 'login', component: LoginComponent},
  {path: '**', component: MainComponent, pathMatch: 'full', canActivate: [AuthGuard]},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Answer №1

To simplify this process, consider creating a Layout module with both Inside and Outside layout components. Include

<router-outlet></router-outlet>
in each component, and then define your routes in the app-routing.module.ts file as follows:

 {
    path: '',
    component: OutsideLayoutComponent,
    canActivate: [ExternalAuthGuard],
    children: [
      { path: '', loadChildren: './modules/auth/auth.module#AuthModule' },
    ]
  },

  {
    path: '',
    component: InsideLayoutComponent,
    canActivate: [AuthGuard],
    children: [
      { path: 'ticket', loadChildren: './modules/ticket-retrieval/ticket-retrieval.module#TicketRetrievalModule' }
      { path: 'error', component: GenericErrorPageComponent },
      { path: 'invalid-session', component: InvalidSessionPageComponent },
      { path: 'un-authorized', component: UnAuthorizedComponent }
    ]
  },

Make sure to create an AuthGuard to manage user authentication status and direct users accordingly based on their login status. The layout will be determined by the specified routes.

Keep in mind that a basic understanding of Angular Lazy Loading is required for this implementation.

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

Executing methods sequentially in the ngOnInit lifecycle hook consecutively

Working with Angular15 has presented me with a challenge. In my app.component.ts file, I have two methods: “ngOnInit()”, as shown below. public ngOnInit(): void { this.getToken(); this.UserLoggedIn(); } I am looking to run the above two functions in ...

Using the CSS :not selector to style certain input elements

Is there a way to style ALL input elements except for specific types without using the :not selector? Here's an example of what I tried: input, input:not(type='email') { background: red; } Unfortunately, this approach didn't work ...

I am struggling to close the horizontal space between two flex items in a row

I'm currently working on a web page design and I'm facing an issue with trying to align a clip-art image and its description in a row using flex. Despite using justify-content to adjust the spacing, there seems to be a persistent gap between the ...

Structured chat interface with unchanging top and bottom sections

I'm currently trying to come up with a way to structure my chatbox so that it has a fixed header at the top and a fixed footer at the bottom, while allowing the chatbox body to scroll within those constraints. I've experimented with various appro ...

Test the HTML element using ngIf async call in Angular 2 with Jasmine unit testing

As I work on writing unit tests for an HTML div with a condition using *ngIf, I come across a specific scenario. <div *ngIf="clientSearchResults$ | async as searchResults" class = 'fgf' #datalist id="mydata" > <app-client-list id=" ...

Is it possible to display a thumbnail image in a separate full-sized window by using CSS or JavaScript?

I am currently utilizing a program called WebWorks 2020.1 that automatically creates <img> tags from my FrameMaker source input when published to DHTML. Unfortunately, I do not have the ability to directly modify the HTML <img> or <a> tag ...

Present a two-column layout using row formatting in Bootstrap with Angular

In my component file, I have an arrayData containing 4 datas, and I am trying to display them in two columns across two rows. <div class="row"> <div class="col-md-6" *ngFor="let cat of myArrayData; let index=index"> <div clas ...

Generating dynamic rowspan values for nested levels within a multi-level table using JavaScript and a JSON array

Trying to dynamically calculate the rowspan for each cell in a nested JSON array, which represents a multi-level table structure. Example of input data: [ { "name": "goal1", "children": [ { ...

Creating a custom video to use as the favicon for my website

Imagine this: With the help of this plugin, you can have a video playing as your site's favicon using the following code snippet: var favicon=new Favico(); var video=document.getElementById('videoId'); favicon.video(video); //stop favicon.v ...

Implementing a singular Django application as the primary authentication system for multiple Django applications

(I am new to Django, so please forgive me if I'm not fully understanding everything ^^") Let's say I have two apps, app1 and app2, and I want them to share the same groups, roles, and permissions using a single database. My thought is to c ...

Positioning an image alongside a row in a table

Looking to incorporate images alongside each row in a table using Html and CSS, similar to the example image below: https://i.sstatic.net/fASNr.png The desired placement for the images is depicted by the red crosses: positioned on the right side of each ...

Unable to display object property on screen after printing Angular 2 array on console

I have written a method in my service: getPost(nid: string): Observable<Post[]>{ let url = "http://test.co.uk/api/v1/basic/" + nid; return this.http.get(url, {headers: this.headers}).map(res => res.json() as Post).catch(err => { ...

Executing a Mongodb server on an android device with the help of Ionic 2

Recently, I've been working on running MongoDB on Android with Ionic 2. My app runs smoothly in my PC browser and fetches data from the MongoDB located in the project folder. However, when trying to run it on an actual device or emulator, I encountere ...

The Art of Div Switching: Unveiling the Strategies

I have a question regarding my website. I have been working on it for some time now, but I have encountered a challenge that I am struggling to overcome. After much consideration, I am unsure of the best approach to take. The issue at hand is that I have ...

Issue with displaying sidebar using blockquote in Bootstrap 4.1.3

After implementing the blockquote class in Bootstrap 4.1.3, all the effects were successfully applied, except for the sidebar. Here's a comparison of how it appears in tutorials: https://i.sstatic.net/qNXrV.png And here is how it appears in my Chrom ...

Having trouble retrieving documents from a nested collection in Firebase

I am attempting to retrieve all documents from Firebase that are based on a query. Here is my current firebase structure: https://i.stack.imgur.com/tXrX8.png Even though I have two documents inside the "ListaFavorite" collection, when I check using empty ...

Combining several objects into a single one in TypeScript while handling duplicate keys

I'm currently using ng2-charts and I'm looking to create a horizontal bar chart. The values are obtained within a keys.forEach loop, resulting in the console.log output for my data as follows: {ReasonA: 5} {ReasonA: 5, ReasonB: 5} {ReasonA: 1, R ...

How can I enlarge an image on hover without disrupting the surrounding content?

After following the instructions provided on how to change image size during mouse hover, I encountered an issue where the resized image caused the rest of the content on the page to shift. Does anyone have suggestions on how to resolve this problem? ...

What is the best method for performing shape subtraction in CSS?

Is there a way to create a frame with a border radius of '150px 30px 30px 30px', but have the top left corner flat instead? See the image for reference here. I tried using a rotated rectangle in the ::before pseudo element to achieve the desired ...

Enhance Your Navbar in Bootstrap 3 by Creating Vertically Expanding Links Relative to Brand Image Dimensions

To best illustrate my issue, I will begin with a screenshot of the problem and then explain what I aim to achieve. Here is the current state of my navbar: Currently, the text of the links on the right side is positioned at the top. Additionally, this is h ...