Refresh the ngrx state data whenever the RouteGuard is triggered

When it comes to ensuring the protected view of an entity, I utilize a RouteGuard to pre-load the necessary data for the desired view into the ngrx store. However, as the corresponding data from the backend can be subject to change over time, it is crucial that each time the route is activated, the old state of the store gets updated with the latest data retrieved from the backend. This update should only occur once the new data has been successfully loaded into the store and made available. It's important to consider scenarios where the entity may have been deleted on the backend in the meantime.

To illustrate this concept further, here is a minimal example: Stackblitz Example

In the current setup, the action GetEntity() is invoked every time the route is accessed, triggering a call to retrieve data from the backend. Despite this, the route still becomes active based on the previous state of the store, which is not the intended behavior. To address this issue, there needs to be a way to invalidate or clear the old state to prevent the route from being activated mistakenly.
Here is the logic within the canActivate function of the RouteGuard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.pipe(select(selectEntityMap)).pipe(
      map(taskMap => Object.keys(taskMap).length > 0),
      tap(loaded => {
        this.store.dispatch(GetEntity()); // trigger backend loading
      }),
      filter(loaded => !!loaded), // wait until the entities have been loaded.
      take(1),
    );
  }

This raises two key questions:

  1. How can I modify the RouteGuard to refresh the data from the backend each time it's activated, ensuring that the route is only enabled with the most recent data?
  2. Is the RouteGuard the appropriate place to handle the logic of fetching data from the backend repeatedly, or are additional adjustments to the state or effects required?

Answer №1

  1. To ensure data refreshment, set a flag when your guard starts and emit only after the data has been refreshed.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // Reset `taskMap` to undefined.
    // Initial value of taskMap should be null (anything except undefined).
    this.store.dispatch(GetEntity());

    return this.store.pipe(select(selectEntityMap)).pipe(
      skipWhile(taskMap => taskMap !== undefined), // Wait until start
      skipWhile(taskMap => taskMap === undefined), // Wait until end

      take(1),
      map(taskMap => taskMap !== null),
    );
  }
  1. The appropriate place for this is within a resolver function.
@Injectable({
providedIn: 'root'
})
export class UserResolverService implements Resolve<any> {
  constructor(private fakeApi: FakeApiService) { }
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.fakeApi.getUsers().pipe(
      catchError((error) => {
      return empty();
      });
    );
  }
}

For more information, visit:

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

Having trouble organizing the date strings in the material table column

In my Angular application, I have a material table with multiple columns that I am sorting using matSort. While I can successfully sort the last two columns in ascending or descending order, I am facing an issue with the first column which contains date va ...

Angular 4 application fails to occupy the entire screen height

Here is how my app.component looks: <div class="wrapper"> <app-header></app-header> <router-outlet></router-outlet> <footer> <section class="page group"> {{ 'COMPANY.address' | translate ...

Issue with rendering object in Three.js ply loader

Just starting out with three.js and Angular 13, using three.js v0.137.0. I'm attempting to load and preview a ply file from a data URL, but all I see after rendering is a bunch of lines, as shown in this screenshot - how the ply file renders. The .pl ...

Tips on updating primeng Panel Menu appearance with scss

I'm looking to customize the color of my panel menu to black. Below is the HTML code I am using. <p-panelMenu styleClass="font-bold text-xs m-0 w-11" [model]="items" [multiple]='false'></p-panelMenu> ...

How can I integrate React-Router Link as a component within Material-UI using Typescript?

Hey everyone, I've encountered an issue while trying to utilize Material UI's component prop to replace the base HTML element of a component. Error: The error message reads: Type 'Props' is not generic. This problem arises from the fo ...

What steps can I take to prevent type errors from affecting my React app during hot-reloading with TypeScript?

Currently, I am facing a "compile" error while working on typescript + react. Below is the configuration I'm using. Is there a way to check types without compromising the build and hot-reload process? Can someone guide me on how to enforce compilation ...

What is the best way to implement the useCallback hook in Svelte?

When utilizing the useCallback hook in React, my code block appears like this. However, I am now looking to use the same function in Svelte but want to incorporate it within a useCallback hook. Are there any alternatives for achieving this in Svelte? con ...

What could be the reason behind the variable remaining unchanged despite being modified?

I have a Pagination class that includes a method for local pagination. export class Pagination { public localPagination(type: IPaginationLocal): void { this.paginationType = type; this.fetchData(); } public fetchData() { this.pag ...

Is there a way to locate all items that satisfy a specific criterion within JSON Data?

Utilizing data from an API-Call, I have established a many-to-many relationship - illustrated with the examples of people and movies. Multiple individuals can watch one movie, and one person can view several movies. In the Angular Frontend, when a person ...

The argument labeled as 'readonly...' cannot be assigned to a parameter labeled as '...[]' in this context

There's a question that resembles mine but addresses a different issue, which can be seen here: Argument of type '...' is not assignable to parameter of type '...' TS 2345 utils.ts (https://www.typescriptlang.org/docs/handbook/2/g ...

Issue encountered during the construction of the Angular project in production

$ ng build --prod Date: 2018-12-06T18:43:56.689Z Hash: e36e17503416de0fc128 Time: 7480ms chunk {0} runtime.ec2944dd8b20ec099bf3.js (runtime) 1.44 kB [entry] [rendered] chunk {1} main.9868d9b237c3a48c54da.js (main) 128 bytes [initial] [rendered] chunk {2} ...

Angular Bootstrap causes misalignment of table column headings based on different properties in object

I have an object with two properties: person and vehicle. Both properties consist of arrays of data. I have separate column headings for the person and vehicle properties and display the data in tabular form. However, the column headings for both propertie ...

Angular - Invoking a different component's method to switch the visibility of a div

I currently have two components - one serving as my header and the other consisting of plain text. The header contains a menu with various options. My goal is to toggle a boolean in the second component and display the complete HTML when an option in the ...

When a service alias is provided in Angular 7, it disrupts the build execution process

After creating a service called MyService and its mocked version - MyServiceMock, I utilized the mock service in my unit tests until the backend is ready, providing and using the results from the mocked service. To avoid future code changes when the backe ...

Angular 6's Nested HTTP Calls Issue: How to Ensure Nested Calls are Executed

Currently, while working with Angular 6, I am facing an issue with two HTTP calls that need to be executed sequentially. The first call is successful, but the second call shows success without actually sending an HTTP request. Interestingly, when I separa ...

Variable type assignment failed due to an error

I'm feeling a bit unsure about whether my query pertains to WebStorm, Angular2, or Typescript. Currently, I have an Angular2 build set up and I am using WebStorm 2016.1.2 for editing purposes. In one of my components, I obtain a reference to a DOM el ...

Tips on sending a parameter to a function with the help of typescript and arrow syntax

I have the following code: const getColumns: ( canRead?: boolean) => ColumnWithId<Data>[] = canRead => [ { Header: 'Name', id: 'name', Cell: props => { retur ...

Making a REST API call with an ID parameter using Angular

I am currently working on an Angular application that interacts with a REST API. The data fetched from the API is determined based on the customer ID, for example: api/incident?customer_id=7. I am unsure of how to incorporate this into the API URL and serv ...

Is now the ideal moment to implement Angular 4?

When considering using Angular 4 for an enterprise SAP system, is it better to stick with Angular 2 and wait for the final release of Angular 4? There have been rapid releases of Angular 4 that may affect our decision. (View changelog) Your suggestions ar ...

What methods can be employed to enhance the User interface further?

I recently started using typescript and decided to migrate an existing project to it. In my middleware functions, which are located in a separate file, I have the following function: const checkCampgroundOwnership = async ( req: Request, res: Response ...