2
votes

I'm learning how to use ngrx effects in Angular. I'm following the ngrx documentation and i try to make my first effect:

In my component i make a dispatch() to load a list of users:

public ngOnInit(): void {
  this.store.dispatch({ type: '[User Page] Load Users' });
}

I create this effect to listen my actions and make the call from my api:

loadUsers$ = createEffect(() =>
  this.actions$.pipe(
    ofType('[User Page] Load Users'),
    mergeMap(() =>
      this.usuarioService.read().pipe(
        map((users) => ({
          type: '[Users API] Users Loaded Success',
          payload: users
        })),
        catchError(() => EMPTY)
      )
    )
  )
);

This is my reducer:

export const initialState = {
  users: []
};

const _userReducer = createReducer(
  initialState,
  on(setUserList, (state, action) => ({ ...state, users: action.payload }))
);

This is my setUserList action:

export const setUserList = createAction('[Users API] Users Loaded Success');

Everything is working but i'm receiving an warning in my vscode when i try to access the action.payload:

Property 'payload' does not exist on type 'TypedAction<"[Users API] Users Loaded Success"> & { type: "[Users API] Users Loaded Success"; }'.ts(2339)

How i can fix this warning?

2

2 Answers

1
votes

You need to define users as a property of your action with the type User[], so:

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

export interface User {
    id: number;
    name: string;
}

export const setUserList = createAction('[Users API] Users Loaded Success', props<{ users: User[] }>());

More about this here.

Then in your effect, I believe you can just do:

map((users) => ({
    type: '[Users API] Users Loaded Success',
    users
})),
0
votes

I fix this warning creating a interface that have the payload property:

import { Actions } from '@ngrx/effects';

export interface IActionWithPayload extends Actions {
  type: string;
  payload?: any;
}

So i typed my action with this interface and the error is gone:

const _userReducer = createReducer(
  initialState,
  on(setUserList, (state, action: IActionWithPayload) => ({
    ...state,
    users: action.payload
  }))
);