Skip to content
Three employees in a modern office meeting room with laptops and a welcome screen.

Angular

Development & Consulting

Front end

Javascript

Social Security

State caching with NGXS in Angular applications

Björn Möllers

Copy Link

Link copied

Today’s web applications are characterized by their modular structure. In this article, you can find out why state management plays an important role and how caching optimizes state management.

The building blocks of a web application have different tasks. Nevertheless, they often use the same data. In an address book, for example, there is one component for the contact list and another for the detailed view of a contact. Both components display the name.

State

Now both components could retrieve the contacts from the backend. But this leads to unnecessary network traffic. This is where the state comes into play. The state represents the “single source of truth”. It provides data across all components. It is therefore sufficient for one component to make the backend call and the other components can load the data from the state.

State caching

In practice, you quickly encounter the problem that a component does not know whether another component has already loaded the required data and saved it in the state. This is where state caching can help.

When using state caching, the system first looks for the required data in the state. If it is available here, the data is loaded from the state. If the data is not available in the state, the data is loaded from the backend.

Implementation

An example is shown below to illustrate the theory in practice. The state management library NGXS is used in the Angular application.

The sample application lists all countries and uses the REST interface from restcountries.eu for this purpose. Clicking on the country abbreviation calls up the detailed information for the country via another endpoint. The detailed information is saved in the state.

Fig. 1: Countries with detailed information, fetched from backend

Fig. 1 shows the list of country abbreviations. Clicking on an abbreviation adds the country to the table with detailed information.

If the same country code is clicked at a later time, the REST interface is no longer called and the data is loaded from the state instead.

export class GetCountryById {
  static readonly type = '[Countries] Get country by ID';
  constructor(public id: string) {
  }
}

@Injectable()
export class CountriesState {
	constructor(private countriesService: CountriesService) { }
	
	@Action(GetCountryById)
	getCountryById(
	{ getState, patchState, setState }: StateContext<CountriesStateModel>,
	{ id }: GetCountryById
	): Observable<any> {
	const countries = getState().countries;
	
	if (!!countries && !!countries[id]) {
	  setState(
	    patch({
	      countries: patch({
	        [id]: patch({
	          isFetchedFromState: true
	        })
	      })
	    })
	  );
	  return;
	}
	
	return this.countriesService.getCountryById(id).pipe(
	  tap((country: Country) => {
	    patchState({
	      countries: {
	        ...countries,
	        [id]: {
	          ...country,
	          isFetchedFromState: false
	        },
	      }
	    });
	  })
	);
	}

}

// Abb. 2

In Fig. 2, there is an if block that checks whether the detailed information is already stored in the state. If this is the case, isFetchedFromState: true is set. This is used to display the source (backend or state) from which the data was loaded on the user interface in the sample application.

Fig. 3: Countries with detailed information, fetched from State

Fig. 3 shows that clicking on “MX” again loads the detailed information from the state (“fetched from State”).

Update state

The “Update population to 100” button is used to change a value as an example. The changed value is sent to the backend and the state is updated if there is a 200 response.

State caching is a simple way of preventing frequent network calls. Fast access to already loaded data also increases user-friendliness. The sample application is published on GitHub: state-caching-with-ngxs.


Angular
Frontend
State management