Skip to content
the poor coder

read data from store i ngrxstore

Poor Man
Published
Reading time
3 min read
On this page

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:

TypeScript

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:

TypeScript

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.

TypeScript

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:

TypeScript

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:

TypeScript

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.

Keep going

2023

how to sort an array

How to Sort an Array If you have an array and you want to order its elements in a specific way, you need to use a sorting algorithm. There are several sorting algorithms available, but two of the most commonly used are…

javascript2 min read
2023

jquery mobile or desktop

jQuery Mobile or Desktop? As a web developer, I have had some experience with both jQuery Mobile and jQuery Desktop. Both frameworks have their pros and cons, and which one to use really depends on the specific project…

javascript1 min read
2023

node.js folder structure

Node.js Folder Structure If you are new to Node.js, it can be daunting to create a folder structure that will work for your project. The structure you choose will depend on the size and complexity of your project. Here…

javascript1 min read
ESC