read data from store i ngrxstore

Reading Data from Store in NgRx Store

If you are using NgRx Store to manage the state of your Angular application, you may need to read data from the store at some point. There are multiple ways to do this, depending on your use case.

Using Selectors

The recommended way to read data from the store is to use selectors. Selectors are functions that take the store's state and return a subset of it. They are used to extract specific pieces of data from the store, and can be composed to build more complex selectors.

Here's an example of a simple selector that returns a list of todos:


import { createSelector } from '@ngrx/store';
import { TodoState } from './todo.state';

export const selectTodos = createSelector(
  (state: { todo: TodoState }) => state.todo,
  (todo) => todo.todos
);

This selector takes the entire store's state and returns the `todos` property of the `TodoState`. To use this selector in a component, you need to inject it and subscribe to it:


import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { selectTodos } from './todo.selectors';

@Component({
  selector: 'app-todo-list',
  template: `
    <ul>
      <li *ngFor="let todo of todos$ | async">{{ todo.title }}</li>
    </ul>
  `
})
export class TodoListComponent {
  todos$ = this.store.select(selectTodos);

  constructor(private store: Store) {}
}

This component subscribes to the `selectTodos` selector and displays the list of todos using `*ngFor`. Note that we are using the `async` pipe to subscribe to the selector and handle the unsubscribe automatically.

Using Store's Value

If you need to read the entire store's state or a specific property of it, you can use the store's `value` property. This property returns the current state of the store.


import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { TodoState } from './todo.state';

@Component({
  selector: 'app-todo-counter',
  template: `
    <p>You have {{ todos.length }} todos.</p>
  `
})
export class TodoCounterComponent {
  todos: Todo[] = [];

  constructor(private store: Store) {
    this.todos = store.value.todo.todos;
  }
}

This component reads the `todos` property from the store's `value` and displays the number of todos. Note that this approach is not recommended for reading data from the store because it bypasses selectors and can cause performance issues.

Using Actions and Effects

If you need to read data from the store as a result of an action, you can use effects. Effects are functions that listen for specific actions and perform side effects, such as fetching data from an API or dispatching other actions.

Here's an example of an effect that fetches todos from an API and dispatches an action to add them to the store:


import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { switchMap, map } from 'rxjs/operators';
import { TodoApiService } from './todo-api.service';
import { addTodos } from './todo.actions';

@Injectable()
export class TodoEffects {
  loadTodos$ = createEffect(() => {
    return this.actions$.pipe(
      ofType('LOAD_TODOS'),
      switchMap(() => this.todoApiService.getTodos()),
      map((todos) => addTodos({ todos }))
    );
  });

  constructor(
    private actions$: Actions,
    private todoApiService: TodoApiService
  ) {}
}

This effect listens for the `LOAD_TODOS` action, fetches todos from an API using the `todoApiService`, and dispatches an action to add them to the store using the `addTodos` action creator. To use this effect, you need to dispatch the `LOAD_TODOS` action:


import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { loadTodos } from './todo.actions';

@Component({
  selector: 'app-todo-list',
  template: `
    <ul>
      <li *ngFor="let todo of todos$ | async">{{ todo.title }}</li>
    </ul>
  `
})
export class TodoListComponent {
  todos$ = this.store.select(selectTodos);

  constructor(private store: Store) {}

  ngOnInit() {
    this.store.dispatch(loadTodos());
  }
}

This component dispatches the `LOAD_TODOS` action when it initializes and subscribes to the `selectTodos` selector to display the todos. Note that the effect will listen for the action and fetch the todos from the API automatically.

Subscribe to The Poor Coder | Algorithm Solutions

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe