Using @ngrx/data I want to handle the result of the getWithQuery
API call differently than the default.
Currently if this returns an array of entities, this gets loaded in the entityCache
directly.
So far I've used the standard pattern shown in the overview:
export const entityMetadata: EntityMetadataMap = {
PurchaseOrder: {}
};
@Injectable({
providedIn: "root"
})
export class PurchaseOrderService extends EntityCollectionServiceBase<
PurchaseOrder
> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super("PurchaseOrder", serviceElementsFactory);
}
}
Instead I want to handle the following API response and load the entities
in the entityCache as the normal getWithQuery
would but also stick the total
elsewhere in my store.
{
"entities": [{...}, {...}, ..., {...}], // list of entities
"total": 100
}
Naturally I get the following error if this API response is returned:
My understanding is that a default reducer gets created and registered for each entity providing the EntityCollectionDataService interface with the add / delete / getAll / getById / getWithQuery / update
methods.
I want to keep these methods but override the getWithQuery
reducer to achieve my aim.
This is mentioned in Customizing Entity Reducer Behavior
But quite often you'd like to extend a collection reducer with some additional reducer logic that runs before or after.
How can this be actually done?
I still get the above error if I try to override getWithQuery
inside my PurchaseOrderService
getWithQuery(params) {
return super.getWithQuery(params).pipe(tap(result => console.log(result)));
}
Managed to get this working using a custom EntityDataService
@Injectable()
export class PurchaseOrderDataService extends DefaultDataService<
PurchaseOrder
> {
constructor(
http: HttpClient,
httpUrlGenerator: HttpUrlGenerator,
logger: Logger,
config: DefaultDataServiceConfig
) {
super("PurchaseOrder", http, httpUrlGenerator, config);
}
getWithQuery(params: string | QueryParams): Observable<PurchaseOrder[]> {
return super.getWithQuery(params).pipe(
tap(res => console.log(res)),
map((res: any) => res.entities)
);
}
}
Then this needs to be registered:
@NgModule({
providers: [PurchaseOrderDataService] // <-- provide the data service
})
export class EntityStoreModule {
constructor(
entityDataService: EntityDataService,
purchaseOrderDataService: PurchaseOrderDataService
) {
entityDataService.registerService(
"PurchaseOrder",
purchaseOrderDataService
); // <-- register it
}
}
And import this alongside EntityDataModule.forRoot({ entityMetadata }),