Tips for effectively managing 404 errors in Angular 10 with modular routing

I'm facing challenges with handling 404 pages within an Angular 10 application that utilizes modular routing architecture.

Here is the structure of my code:

|> app
|-- app.module.ts
|-- app-routing.module.ts
|-- app.component{ts, spec.ts, scss, html}
|-> pages
|--- pages.module.ts
|--> home-page
|---- home-page.module.ts
|---- home-page-routing.module.ts
|---> home-page
|----- home-page.component{ts, spec.ts, scss, html}
|--> test-page
|---- test-page.module.ts
|---- test-page-routing.module.ts
|---> test-page
|----- test-page.component{ts, spec.ts, scss, html}

The global app-routing module has a 404 handler configured as seen below:

...
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },

  // If the following line is not commented out,
  // You are unable to navigate to either the 'Home' or 'Test' pages.
  // { path: '**', component: PageNotFoundComponent },
];

...

The issue I am encountering is that Angular resolves to the global 404 handler in ./app/app-routing.module.ts instead of the intended page route.

I have provided a sample StackBlitz showcasing this behavior (Note: The StackBlitz example is running Ng12, but our app is using Ng10 with similar behavior)

My objective is to implement a global 404 handler or redirection functionality while maintaining separate definitions for page routes within their respective module-routing files.

Is it possible to achieve this, and if so, how?

Answer №1

Upon reviewing your Stackblitz, it appears that the issue lies in the order of imports within the AppRoutingModule, with it being imported before the PagesModule.

To resolve this, ensure that you import the PagesModule first as its routes should take precedence.

  imports: [
    BrowserModule,
    RouterModule,
    FormsModule,
    PagesModule,
    AppRoutingModule,
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

An alternative (and preferable) solution would be to implement lazy loading for the module:

const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  {
    path: '',
    loadChildren: () =>
      import('./pages/pages.module').then((m) => m.PagesModule),
  },
  { path: '**', component: PageNotFoundComponent },
];

This approach eliminates the need to import the entire PagesModule into your AppModule.

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

Looking to set up a web service that can handle incoming posts, but unsure about the best way to send a response back to jQuery

Good morning, I have a Go code that processes a JSON post request and performs certain actions. However, I am looking to send back either the result or a message to jQuery. package main import ( "fmt" "log" "net/http" "encoding/json" ...

What's the best way to constrain a draggable element within the boundaries of its parent using right and bottom values?

I am currently working on creating a draggable map. I have successfully limited the draggable child for the left and top sides, but I am struggling to do the same for the right and bottom sides. How can I restrict the movement of a draggable child based o ...

The data point on jqPlot does not display in full

I've been working on creating a chart with jqPlot to display data for each hour. It's mostly going well, but there's an issue where the first and last data points are not showing correctly - part of the circle is getting cut off. Here' ...

Autocomplete feature integrated within search bar

I'm currently experimenting with merging MUI autocomplete and MUI searchbar to create a Searchbar that provides suggestions. I have attempted the following: https://codesandbox.io/s/material-demo-forked-cthpv import React from "react"; impo ...

Establishing the highest allowable value limit in cleave

I've integrated cleave.js into my Vue.js project to create a date input field. Here's the option configuration I used: <cleave :options="{ date: true, datePattern: ['m', 'd','Y'] ...

Tracking the latency of WebSockets communications

We are in the process of developing a web application that is highly responsive to latency and utilizes websockets (or a Flash fallback) for message transmission to the server. While there is a fantastic tool known as Yahoo Boomerang for measuring bandwidt ...

Waiting for an Element to Become Visible in Selenium-Webdriver Using Javascript

When using selenium-webdriver (api docs here), how can you ensure that an element is visible before proceeding? Within a set of custom testing helpers, there are two functions provided. The first function successfully waits for an element to exist, howeve ...

What is the reason this switch statement functions only with one case?

Why is the switch statement not functioning properly? It seems to correctly identify the values and match them with the appropriate case, but it only works when there is a single case remaining. If there are multiple cases to choose from, nothing happens. ...

Select from a list to save

My goal is to create a feature where users can select a hotel name, number of days, guests, and peak time, the system will calculate them together and give a sum. Furthermore, I wish to store all user selections in the database, including the calculated to ...

Create queries for relays in a dynamic manner

I'm using Relay Modern for my client GraphQL interface and I am curious to know if it is possible to dynamically generate query statements within Relay Modern. For example, can I change the original query structure from: const ComponentQuery = graphq ...

Retrieving various pieces of data in Express

After scouring through various websites, I am still unclear on how to extract multiple GET variables using Express. My goal is to send a request to a Node.JS Express server by pinging the URL with: file_get_contents('http://127.0.0.1:5012/variable1/v ...

Infuse services from an Angular application into specialized components

I am currently working on developing an Angular application that adheres to the following principles: Creating a global application with services, components, and child modules Having one of the components load custom elements based on user requirements U ...

Is it possible to utilize the Node.JS PassThrough stream as a straightforward input buffer?

In my Node.js application, I am utilizing a subprocess referred to as the "generator" to produce data. The challenge arises when the generator occasionally outputs a large chunk of data at a speed of around 50MB/s, while generally operating at a much slowe ...

How can I perform email validation using Angular 6?

I am working on an Angular6 form that includes a field for email input. Currently, the email field has proper validation which displays an error message when an invalid email is entered. However, even if the error message is shown, the form is still saved ...

How to retrieve the current event handler's value with jQuery

To assign an onclick event handler using jQuery, I simply use the following code: $('#id').click(function(){ console.log('click!'); }); Now, my question is how can I retrieve a reference to the function that is currently handling th ...

Is there a way to serve server-side rendered content exclusively to search engine crawlers like Google Bot, without SSR for regular users in Next.js?

With a staggering number of users visiting the site every day, we are making strides to enhance our visibility on Google by implementing SSR (which may sound unbelievable) and achieving a richer preview when content is shared on messaging platforms. As th ...

Is there a way to create a tuple property that can be called like a

I have a specific function in my code: function test(cb: Function | number) { let item = { height: 0} if(typeof cb === 'number') { item.height = cb; } if(typeof cb === 'object') { item.height = cb(); } } This function ...

Create a custom loading spinner for a jQuery AJAX request

How can I add a loading indicator to my Bootstrap modal that is launched from a link? Currently, there is a 3-second delay while the AJAX query fetches data from the database. Does Twitter Bootstrap have built-in functionality for this? UPDATE: Modified J ...

different ways to retrieve component properties without using inheritance

In order to modify certain properties of components after login, such as the "message" property of HomeComponent and the "age" property of UserComponent, I am unable to inherit the component class. What are some alternative methods to achieve this? Authen ...

Setting a global variable in the JavaScript code below

Is there a way to make the modal variable global by setting it as var modal = $("#modal"); ? The code snippet below includes the modal variable and is not functioning properly. It needs to work correctly in order to display: "Hello name, You have signed u ...