Achieve a seamless redirection to the 404 component in Angular without altering the browser URL, while ensuring that the browsing

Whenever my backend sends a 404 error (indicating that the URL is valid, but the requested resource is not found, such as

http://localhost:4200/post/title-not-exist
), I need Angular to automatically redirect to my NotFoundComponent without altering the URL visible in the browser.

The simplified code snippet is provided below:

constructor(private router: Router, private location: Location) {}

handleError(err: HttpErrorResponse) {
  switch (err.status) {
    case 404:
      url = this.router.routerState.snapshot.url;
      // '**' is set in the app-routing.module.ts
      // { path: '**', component: NotFoundComponent }
      this.router.navigate(['**'], { replaceUrl: false });
      // Strange behavior observed here
      // Without the setTimeout(), replaceState will not work
      setTimeout(() => {
        this.location.replaceState(url);
      });
      break;

    default:
      break;
  }
  return throwError(err);
}

Although I can successfully redirect to the NotFoundComponent without changing the URL, there are some issues to address:

  1. My browsing history ends up showing redundant entries like:
    /post/title-exist/post/not-exist/post/not-exist
    when it ideally should be
    /post/title-exist/post/not-exist
    This also causes the back function to become stuck at a certain point.
  2. If the setTimeout() is omitted, location.replaceState() fails to update properly and the URL in the browser displays as /** instead of reverting back to the previous snapshot URL.

Answer №1

Important Update

Remember to utilize skipLocationChange instead of replaceUrl in your code snippet. Further details can be found here.

Original Explanation

The critical adjustment lies in toggling the replaceUrl parameter within this.router.navigate function from false to true, as shown below:

this.router.navigate(['**'], { replaceUrl: true });

Rationale behind this change:

  • By setting replaceUrl to false, a new history entry is added, thereby extending the browser's history stack like so:

/post/title-exist/post/title-not-exist/**

Subsequently, invoking replaceState() alters the /** entry to /post/title-not-exist, resulting in the following history trail:

/post/title-exist/post/title-not-exist/** /post/title-not-exist

  • Conversely, when replaceUrl is set to true, it directly modifies the existing history stack, leading to a progression as follows:

/post/title-exist/post/title-not-exist /**

Ultimately, with assistance from replaceState(), the revised history appears as:

/post/title-exist/post/title-not-exist /** /post/title-not-exist

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

Leveraging CustomPipe with ngModel in Angular 7 and beyond

In my application, I am facing an issue with a date calendar picker input that is storing dates on a server and returning them onInit. The problem arises when the date is not stored or picked, as it returns 01/01/0001 numbers. My goal is to have the input ...

NG build error: Module parsing failed due to an unexpected token - no updates made

Two days ago, out of nowhere, we started encountering build errors during deployment using GitLab CI. No alterations have been made to the build scripts, and none of the versions of NPM, NG, or Angular have been modified. The same compilation commands cont ...

Discover how to capture a clicked word within the Ionic Framework

I've been working on an app using the Ionic Framework. I am trying to figure out how to detect when a word is pressed in my application. One solution I tried involved splitting the string into words and generating a span with a click event for each on ...

Guide to resetting a CSS animation with pure JavaScript

My flexbox contains 4 images, each triggering an animation on hover. However, the animation stops if I hover over the same image again. I have tried various JavaScript solutions found online to restart the animation, but none seem to be working for me. S ...

What is the best way to add an array to my JSON object in Javascript?

I'm currently in the process of formatting an array into a JSON object for API submission. Struggling to find the right method to transform my array into the desired structure. This is what my array looks like: data: [ ["Lisa", "Heinz", "1993-04 ...

Ways to center the percentage on the progress bar

I'm having an issue with positioning the percentage 100% in the center of the element. I attempted adjusting the spacing in the JavaScript code, but so far it hasn't been successful. Here is the current output for the code: http://jsfiddle.net/G ...

The issue with Nextjs getStaticPaths is that it is not retrieving data from Firebase Firestore

I'm encountering an issue with fetching dynamic data from firestore in nextjs using getStaticPaths. While rendering the data from firestore with getStaticProps works, I'm facing a problem when trying to access specific item details as it leads me ...

Angular 12 - Encountering an issue with undefined properties when trying to access 'values'

Currently in the process of upgrading Angular Version from 8 to 12. Successfully made the upgrade from 8 to 11 without any issues. However, upon updating Angular to version 12, encountered an error stating "loadComponent TypeError: Cannot read propert ...

Tips for troubleshooting the error message: "The relative import path "$fresh/dev.ts" is not prefaced with / or ./ or ../"

My editor is showing a TypeScript error for a Deno module I am working on. The import path "$fresh/dev.ts" should be prefixed with / or ./ or ../ I have an import_map.json file set up with the following content. { "imports": { "$fre ...

an all-encompassing loading animation designed specifically for updates to location.href

We have a situation where a customer's website is displaying extremely slowly within an iFrame, taking about 7 seconds to load. All we can do is provide the customer with a JavaScript file for inclusion on their site, as they are not willing to make a ...

Create a navigation link in Vue-bootstrap that directs to an 'external program'

After deciding to use vue-bootstrap instead of just bootstrap for its additional features like tabs, I made the choice to rewrite the navigation using it as well. However, I encountered an issue where the links in the navigation menu are pointing to the co ...

What is causing the issue with $(document).append() method in jQuery version 1.9.1?

Why is the following code not functioning properly in jQuery 1.9.1? It worked fine in previous versions. $(function () { $(document).append(test); document.write('done'); }); var test = { version: "1.0", }; JSFiddle: http://jsfiddl ...

Switching classes in real time with JavaScript

I'm struggling to understand how to toggle a class based on the anchor text that is clicked. <div> <a id="Menu1" href="#">Menu</a> <div id="subMenu1" class="subLevel"> <p>stuff</p> </div> <div> <a i ...

Leveraging Async/Await to track error counts across three distinct loops, each invoking an asynchronous function in every iteration

While I have experience with Callbacks, Async/Await and Promises are new concepts to me. In my node.JS server project, I am faced with the challenge of counting errors generated by thousands of asynchronous calls from three different async functions. My g ...

Utilizing AXIOS in React functional components for REST API integration

When trying to parse Rest API responses with JSON using AXIOS in a functional component, the issue arises where it initially returns an empty array before displaying the exact API response data after rendering. This can be confusing as the return function ...

Retrieving data from an HTML Table using Javascript

I am in the process of designing a dynamic web form that populates from a stored procedure. The form consists of a table with a dropdown list, a text box, and a label. While I can successfully retrieve data from the dropdown and text box, I am facing diffi ...

Express encountered a simple web application error

Greetings, this marks my debut post. As a coding novice, I have been following tutorials on opentutorials.org/course/2136/11950 I attempted to troubleshoot errors in my code, but unfortunately I've hit a roadblock. Upon accessing the site, it displa ...

Oops! The type error is indicating that you tried to pass 'undefined' where a stream was required. Make sure to provide an Observable, Promise, Array, or Iterable when working with Angular Services

I've developed various services to interact with different APIs. The post services seem to be functioning, but an error keeps popping up: ERROR TypeError: You provided 'undefined' where a stream was expected. Options include Observable, ...

simulating the use of `usePrompt` in react-router-dom version 6

Prompt.js import { unstable_usePrompt as usePrompt } from 'react-router-dom'; // eslint-disable-next-line react/prop-types export default function CustomPrompt({ when, message }) { usePrompt({ when, message }); return null; } CustomPrompt.t ...

Retrieve a specific value in HTML <a> tag using JavaScript-Ajax in Django

I am currently working with Python 3 and Django. Within my HTML code, I have the following: {% for category in categories() %} <li class="c-menu__item fs-xsmall"> <a href="#" id="next-category"> {{ category}} & ...