NgRx Life Cycle

NgRx Top Interview Questions and Answers

First I would like to thanks the NgRx team for such a great library and for nice documents. Below answers are taken by NgRx official doc.

Go to Docs: https://ngrx.io/docs

💡 What is NgRx?

NgRx is a library for building reactive applications in Angular, inspired by Redux, a very useful and predictable state management container for JavaScript apps.
It was developed by Rob Wormald, an Angular Developer Advocate in 2013.

It provides below great features –

  • Manage application Global (Centralized) and Local state.
  • Promote a clean and dump component architecture.
  • Entity collection management.
  • Integration with the Angular Router.
  • Developer Tooling

💡 Why use NgRx Store for State Management?

NgRx Store provides state management for creating high maintainable applications through the use of a single state. It provides actions in order to express state changes. In case, some components don’t need a wide state, ngRx use ComponentStore which provides a solution for local state management.

💡 When choosing ngRx?

In particular, you might use NgRx when you build an application with a lot of user interactions and multiple data sources, or when managing state in services that is no longer sufficient.
The store is built on a single, immutable data structure. ngRx provides selector functions that optimize retrieving data from your state. ngRx provides Effects and Store for interactions with external resources like network requests.

Read here for more details.

💡 Explain the Core Concept of ngRx.

  • Store – We can say it database of the application. It is immutable and only altered by actions.
  • Actions – dispatched from components and services.
  • Reducers – Reducers are pure functions that are responsible for state changes. It takes the current state and the latest action to create a new state.
  • Meta-reducers – These are similar to middleware used in Redux. It allows us to pre-process actions before normal reducers functions are called.
  • Selectors – These are also pure functions to obtaining slices of store state instead of the full state.
  • Effects – Without ngRx, components are responsible to connect with external APIs using services. So ngRx effects provide a way to interact with external sources (services, network requests, web sockets, etc.) and isolate them from the component.

💡 Explain ngRx Life Cycle.

Please see the first flow diagram of this post to understand the lifecycle.

💡 What is state “ select “ function?

we can access one of the states by using the select function. The select function picks the desired state from the store and returns an Observable.

 this.store.select('products').subscribe((state => this.products = state));

💡 What is createAction function in ngRx and how it differs from the old way to create Actions?

The createAction is a factory function that returns an object of Action interface when called.

Without createAction –

import { Action } from '@ngrx/store';

export enum ProductActionTypes = {
AddProduct = '[Product] Add Product',
RemoveProduct = '[Product] Remove Product',
}

export class AddProduct implement Action {
readonly type = ProductActionTypes.AddProduct;
 constructor(public payload: any){}
}

✔ New way to create actions –

import { createAction, props } from '@ngrx/store';

export const addProduct = createAction('[Product] Add Product');

export const removeProduct = createAction('[Product] Remove Product', props<{productId: number}>());

💡 How can we pass extra information with Actions?

// Action Interface
interface Action {
  type: string;
}

Above is the interface of Actions. We can add properties to an action to provide additional context or metadata for an action.

{
  type: '[Login Component] Login',
  username: string;
  password: string;
}
import { createAction, props } from '@ngrx/store';

export const login = createAction(
  '[Login Component] Login',
  props<{ username: string; password: string }>()
);

// call
store.dispatch(login({ username: username, password: password }));

💡 Is Reducer work synchronously or asynchronously?

Reducers are pure functions that return the same output for a given input without any side effects. reducers handle state transition synchronously.

💡 Explain a new way to create reducer function?

ngRx introduced new “createReducer” function that allows creating a reducer without a switch statement. It uses the "on" function to make a distinction between the action types and returns a new reference of the state.

old way —-> we use a switch statement.

import {ProductActionTypes, ProductActions} from './actions';
export const initialState = [];

export function reducer(state = initialState, action: ProductActions) {
switch (action.type) {
        case ProductActionTypes.AddProduct: 
            return [...state, action.payload]
        case ProductActionTypes.RemoveProduct: 
            let product = action.payload;     
            return state.filter((el)=>el.id != product.id)
        default: 
            return state;
    }
}

✔ New way with createReducer function –

import { Action, createReducer, on } from '@ngrx/store';

export const initialState: State = {
  quantity: 0,
  productName: 0,
};

export const createReducer(initialState, 
	on(ProductActionTypes.AddProduct, 
		state => ({...state, quantity: state.quantity + 1})
	),
	on(ProductActionTypes.RemoveProduct, 
	(state, {product} => ({...state, id: state.ids.filter(id => id !== product.id)})) )
)

💡 What is Memoization in ngRx?

Memoization is an optimization technique that is used to speed up computer programs by storing results of expensive functions & return the same cached result when that function is called again with the same input parameters.

In ngRx, Selectors provides a feature of memoization using createSelector & createFeatureSelector functions that keep track of invoked function with the latest arguments. Because selectors are pure functions, so it returns the last result when reinvoking your selector function with the same arguments. It is very helpful in terms of application performance.

import { createSelector } from '@ngrx/store';

💡 What are the advantages of Effects in ngRx?

  1. Effects isolate side effects from components and make them pure components that are responsible for only select state and dispatch actions.
  2. Effects are long-running services or operate big computation that listens to an observable of every action dispatched from the Store.
  3. Effects handle tasks, which are synchronous or asynchronous and return a new action.
@Injectable()
export class ItemEffects {

  loadItems$ = createEffect(() => this.actions$.pipe(
    ofType('[Item Component] Load Items'),
    mergeMap(() => this.itemService.getAll()
      .pipe(
        map(items => ({ type: '[Items API] Items Loaded', payload: items })),
        catchError(() => EMPTY)
      ))
    )
  );

  constructor(
    private actions$: Actions,
    private itemService: ItemService
  ) {}
}

💡 How to register Effects in the app.module?

import { EffectsModule } from '@ngrx/effects';
import { ProductEffects } from './effects/product.effects';

@NgModule({
  imports: [
    EffectsModule.forRoot([ProductEffects])
  ],
})
export class AppModule {}

Note: Effects start running immediately after the AppModule is loaded to ensure they are listening for all relevant actions as soon as possible.

Best Practices for Writing Angular Apps | Angular Guidelines

Angular NgModule, AOT, and DI, and EntryComponents with example

NgRx Top Interview Questions and Answers

Leave a Reply

Your email address will not be published.