Home > Blockchain >  Angular full screen 404 page with router-outlet
Angular full screen 404 page with router-outlet

Time:01-31

So I'd like to create a full screen 404 page not related to the main content's router-outlet.

Because right now when I visit a not-existing page the 404 page content is displayed inside the router outlet, with the header, navbar etc still in place.

However I'd like to have it like the WHOLE SCREEN in full screen 404 page. Something like this, just without the nav bar on top: https://www.blizzard.com/en-us/asdasdasd

This is what I have so far:

app.component.html

<div >
  <app-navbar></app-navbar>
  <!--<app-header></app-header>-->
  <router-outlet></router-outlet>
  <app-footer></app-footer>
</div>

app-routing.module.ts

{
    path: '**',
    pathMatch: 'full',
    component: NotFoundComponent
}

NotFoundComponent:

<body>
  <p>404</p>
</body>

Thanks in advance.

CodePudding user response:

I didn't try this before, but you can create a notFoundPage.html file and place it under the assets folder, then you need a redirecting function in NotFoundComponent.ts to the HTML file. This approach is similar to working with sitemaps. You can check this link for more info.

CodePudding user response:

Yes you can simply do it this way

1: First create a service where create a new subject

navIsVisibile = new BeheviourSubject(true);

2: Then when the 404 page is loaded just update the state of navIsVisibile.next(false). This need to be done on mount

3: You have to change to visibility again on destroy of the 404 component

`navIsVisibile.next(true)

4: Subscribe to the navIsVisibile in app.component.ts and based on navIsVisibile its state show the nav

Please check Behaviour subject doc: https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject

CodePudding user response:

I think the easiest way to do this is to check the component name in the navbar component and hide the navbar if the current component is the NotFoundComponent
Here is navbar.component.ts

export class NavbarComponent {
  component: string;
  found: boolean = true;
  constructor(router: Router ) { 
    router.events.subscribe(val => {
      if (val instanceof ActivationEnd) {
        this.component = val.snapshot.component['name'];
        if(this.component == 'NotFoundComponent'){
          this.found =false;
        }
      }
    });
  }
}

And the condition in navbar.component.html will be as below

<nav *ngIf='found'>
  <!-- your navbar -->
</nav>

CodePudding user response:

There are multiple ways to accomplish what you want.

1. Overlay (quick&dirty):

What you did looks quite good. Just don´t try to replace everything - just lay over.

In not-found.component.scss

:host {
  position: fixed;
  width: 100%;
  height: 100%;
}

And do within NotFoundComponent whatever you like. This is defintely not the cleanest solution (just think about screen readers...), but it is quite simple and gets the job done.

2. Service to hide NavBar, Header and Footer (clean, little more complex)

Create an AppService that can control basic app features like showing and hiding top-level components.

Do something like that in app.service.ts:

@Injectable({
  providedIn: 'root'
})
export class AppService {

  showNavigation$: BehaviorSubject<boolean>;
  showHeader$: BehaviorSubject<boolean>;
  showFooter$: BehaviorSubject<boolean>;

  constructor() { 
    this.showNavigation$ = new BehaviorSubject<boolean>(true);
    this.showHeader$ = new BehaviorSubject<boolean>(true);
    this.showFooter$ = new BehaviorSubject<boolean>(true);
  }
}

Inject AppService to your AppComponent and bind the components to the fields. app.component.html:

<div >
  <app-navbar *ngIf="appService.showNavigation$ | async"></app-navbar>
  <!--<app-header *ngIf="appService.showHeader$ | async"></app-header>-->
  <router-outlet></router-outlet>
  <app-footer *ngIf="appService.showFooter$ | async"></app-footer>
</div>

Inject the service to NotFoundComponent and set the "show" properties to false.

appService.showNavigation.next(false);
appService.showHeader.next(false);
appService.showFooter.next(false);

That is a clean and elegant way to control app-wide features from child components.

3. More hierarchy in navigation (clean, but slightly messes up the url)

Empty your AppComponent so that it contains only the RouterOutlet.

app.component.html:

<div >
  <router-outlet></router-outlet>
</div>

Now add something like a master-page.

master.component.ts:

<app-navbar></app-navbar>
<!--<app-header></app-header>-->
<router-outlet></router-outlet>
<app-footer></app-footer>

At last define the routes with a little more hierarchy like this:

app-routing.module.ts:

{
  path: 'side',
  component: MasterComponent,
  children: [
    {...your actual routes here...},
    {
      path: '*',
      redirectTo: '/not-found'
  ]
},
{
  path: 'not-found',
  component: NotFoundComponent
}

That way the master page is not even used for the not-found route.

  •  Tags:  
  • Related