Can someone help me troubleshoot this issue? It's my first time using state management.
The result I get when trying to fetch it from the state is not what I expected.
https://i.sstatic.net/QD7o5.png
Here is the reducer:
import {createReducer, on} from '@ngrx/store';
import {getBooksSuccess} from './book-list.actions';
import {Book} from '../../models/book.model';
const initialState: Array<Book> = [];
export interface BookState {
bookList: Book[];
}
export const bookReducer = createReducer(
initialState,
on(getBooksSuccess, (state, action) => {
return {
...state,
books: action,
};
})
);
export function BookReducer(state, action) {
return bookReducer(state, action);
}
Next is the action:
import {createAction} from '@ngrx/store';
import {Book} from '../../models/book.model';
export const FETCH_BOOKS_START = '[Books] books start';
export const FETCH_BOOKS_SUCCESS = '[Books] books Success';
export const getBooks = createAction(
FETCH_BOOKS_START
);
export const getBooksSuccess = createAction(
FETCH_BOOKS_SUCCESS,
(books: ReadonlyArray<Book>) => books
);
Then we have the effect:
fetchBooks$ = createEffect(() => {
return this.actions$.pipe(
ofType(getBooks),
mergeMap(() => {
return this.bookService.getBooks().pipe(
map((bookList) => {
this.books = this.bookService.mapToBooksModel(bookList);
return getBooksSuccess(this.books);
})
);
})
);
});
The service class looks like this:
@Injectable({
providedIn: 'root',
})
export class BookService {
responseData: BookResponseData[];
bookList: Book[];
constructor(private http: HttpClient) {
}
getBooks(): Observable<BookResponseData[]> {
return this.http.get<BookResponseData[]>(
`./assets/books.json`,
);
}
mapToBooksModel(books: BookResponseData[]) {
this.bookList = books;
return this.bookList;
}
}
Next up is the model class definition:
export interface Book {
id: string;
name: string;
author: string;
}
export interface BookResponseData {
id: string;
name: string;
author: string;
}
Here's the selector:
import {BookState} from './book-list.reducer';
import {Book} from '../../models/book.model';
import {createSelector} from '@ngrx/store';
export const BOOK_STATE_NAME = 'bookList';
export const bookSelector = createSelector(
(state: BookState) => state.bookList,
(books: Array<Book>) => books
);
And finally, the BookListComponent:
export class BookListComponent implements OnInit {
book$: Observable<Book[]>;
books: Book[];
constructor(private store: Store<BookState>) {}
ngOnInit(): void {
this.store.dispatch(getBooks());
this.store.select(bookSelector).pipe().subscribe( books => {
this.books = books;
console.log(this.books);
});
}