angular - SelectAll fra ngrx/entity velger ingenting
Introduksjon
Jeg har litt problemer med å få selektoren min til å fungere. Komponenten min oppdateres ikke med bøker fra FakeApiService selv om jeg kan se at kallet blir gjort. Så handlingene og effektene fungerer.
Jeg tror problemet er relatert til min bruk av @ngrx/Entity. Spesielt dette
export const getBooksState = createFeatureSelector<DemoState>('demo');
og
export const { selectAll } = fromBook.adapter.getSelectors();
Jeg har sett opplæringsvideoer hvor de gir en seleksjonsfunksjon til getSelectors(), men det burde ikke være nødvendig.
Jeg håper noen kan se hvor jeg gjør feil, og hvis noen har noen forslag til strukturen/oppsettet, er jeg helt åpen :)
Her er mitt oppsett.
Versjoner
- Angular: 6.0.0
- rxjs 6.1.0
- typescript 2.7.2
- webpack 4.6.0
- @ngrx/effects 5.2.0
- @ngrx/entity 5.2.0
- @ngrx/router-store 5.2.0
- @ngrx/schematics 5.2.0
- @ngrx/store 5.2.0
- @ngrx/store-devtools 5.2.0
ngRx
funksjon/butikk/handlinger/bok. handlinger.ts
import { Action } from '@ngrx/store';
import { Book } from '../../models/book';
export enum BookActionTypes {
Load = '[Book] Load',
LoadSuccess = '[Book] Load Success',
LoadFail = '[Book] Load Fail'
}
export class LoadBooksAction {
readonly type = BookActionTypes.Load;
}
export class LoadBooksSuccessAction implements Action {
readonly type = BookActionTypes.LoadSuccess;
constructor(public payload: Book[]) {}
}
export class LoadBooksFailAction {
readonly type = BookActionTypes.LoadFail;
}
export type BookActions
= LoadBooksAction
| LoadBooksSuccessAction
| LoadBooksFailAction;
feature/store/effekter/bok.effekter.ts
import { Injectable } from '@angular/core';
import { Actions, Effect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
import { FakeApiService } from '../../services/fake-api.service';
import { LoadBooksFailAction, LoadBooksSuccessAction, BookActionTypes } from '../actions/book.actions';
@Injectable()
export class BookEffects {
constructor(
private fakeService: FakeApiService,
private actions$: Actions,
) {}
@Effect()
loadBooks$ = this.actions$
.ofType(BookActionTypes.Load)
.pipe(
switchMap(() => this.fakeService.getBooks()),
map(books => (new LoadBooksSuccessAction(books))),
catchError(error => of(new LoadBooksFailAction()))
);
}
feature/store/reducers/book.reducer.ts
import { EntityState, createEntityAdapter } from '@ngrx/entity';
import { Book } from '../../models/book';
import { BookActionTypes, BookActions } from './../actions/book.actions';
export interface BooksState extends EntityState<Book> {}
export const adapter = createEntityAdapter<Book>();
const initialState: BooksState = adapter.getInitialState();
export function reducer(state = initialState, action: BookActions ): BooksState {
switch (action.type) {
case BookActionTypes.LoadSuccess: {
return adapter.addAll(action.payload, state);
}
default: {
return state;
}
}
}
funksjon/butikk/reduktorer/index.ts
import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';
import * as fromOrder from './book.reducer';
export interface DemoState {
demo: fromBook.BooksState;
}
export const reducers: ActionReducerMap<DemoState> = {
demo: fromBook.reducer
};
export const getBooksState = createFeatureSelector<DemoState>('demo');
funksjon/butikk/velgere/bok.velgere.ts
import * as fromBook from '../reducers/book.reducer';
export const {selectAll} = fromBook.adapter.getSelectors();
Vinklet
feature/feature.module.ts
@NgModule({
imports: [
CommonModule,
StoreModule.forFeature('demo', reducer),
EffectsModule.forFeature([BookEffects])
],
providers: [FakeApiService],
declarations: []
})
export class DemoModule { }
funksjon/komponenter/bok-visning.komponent.ts
@Component({
selector: 'app-book-view',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<book-list [books]="books$ | async"></book-list>`
})
export class BookViewComponent implements OnInit {
books$: Observable<Book[]>;
constructor(private store: Store<fromStore.BooksState>) {
this.books$ = this.store.pipe(select(fromStore.selectAll));
}
ngOnInit() {
this.store.dispatch(new bookActions.LoadBooksAction());
}
}
Svar #1
Problemet ligger i din Selector; Du må sende inn bok/demo-tilstand til getSelectors-funksjonene
import * as fromBook from '../reducers/book.reducer';
import { getBooksState } from '../reducers';
export const selectBookState = createSelector(
getBooksState,
state => state.demo
);
export const {
selectAll
} = fromBook.adapter.getSelectors(selectBookState);
ta en titt på mitt repo og URL
https://github.com/rijine/itunes-album-angular/blob/master/src/app/album/store/selectors/albums.selector.ts
