Reputation: 517
I trying to implement a store using Angular and ngrx and I have some problems to load values stored in the store. My items are loaded using a service and it seems to work properly.
Here is my code:
// app.module.ts
StoreModule.forRoot({
todoReducer
}
// --------------------------
//todo.reducer.ts
export function todoReducer(state: TodoState, action: Action) {
return reducer(state, action);
}
const reducer = createReducer(
initialState,
on(TodoActions.BEGIN_GET_TODOS, state => state),
on(TodoActions.SUCCESS_GET_TODOS, (state: TodoState, {payload}) => {
return {
...state,
todos: payload,
selectedTodo: null
};
}),
...
// --------------------------
// todo.effects.ts
getTodos$: Observable<Action> = createEffect(() =>
this.$action.pipe(
ofType(TodoActions.BEGIN_GET_TODOS),
mergeMap(() =>
this.todoService.getTodos().pipe(
// Success http call
map((data: Todo[]) =>
TodoActions.SUCCESS_GET_TODOS({payload: data}),
),
// Error http call
catchError((error: Error) =>
of(TodoActions.ERROR_TODOS(error)),
),
)
)
)
);
// --------------------------
// todo-list.component.ts
export class TodoListComponent implements OnInit {
todos: Observable<Array<Todo>>;
ngOnInit(): void {
this.todos = this.store.select(state => state.todos);
this.store.dispatch(TodoActions.BEGIN_GET_TODOS());
}
}
// --------------------------
// todo-list.component.html
<tr *ngFor="let todo of todos | async" (click)="onSelect(todo)">
My problem is that when the service loads all the todos, my component seems to not be updated. I always have an empty list of items in the html. But in the log I can see that the service properly retrieves my items from backend...
I'm certainly doing something wrong, but I don't know what. Any suggestions?
PS: I'm on Angular 8.2.12 and ngrx 8.6.0
Upvotes: 1
Views: 237
Reputation: 52867
You need to pass an ActionReducerMap to StoreModule.forRoot()
.
StoreModule.forRoot({ 'todoState', todoReducer });
Make sure your state is initialized:
const initialState = { todos:[], selectedTodo: null };
Selecting Slices of State
Your selector should start from the root and include the state:
this.todos = this.store.select(state => state.todoState.todos);
Or even better, you should be using Selectors:
export const selectAll = createSelector<any, any, any>(state => state.todoState, todoState => todoState.todos);
Which you can use like this:
this.store.select(selectAll);
Upvotes: 0