I'm new to NgRx entities... And don't know how to take advantage of it in order to update my state. I just like to satisfy my action right in my effect.
This is my effect:
updateItem$ = createEffect(() =>
this.actions$.pipe(
ofType(ItemsActions.updateItem),
concatMap(({ url, item }) => {
return this._itemsProxy.updateItem(url, item).pipe(
map((item: { id:number; name: string; }) => {
// I get an error that says:
// Type '{ id: number; name: string; }' is not assignable to type 'Update<{ id:number, name: string }>'
// So how should I satisfy my action?
return ItemsActions.updateItemSuccess({ item })
}),
catchError((error) => of(ItemsActions.failure({ error }))),
);
}),
),
);
This is my action group:
export const ItemsActions = createActionGroup({
source: 'Items/API',
events: {
updateItem: props<{ url: string; item: { id: number; name: string; } }>(),
updateItemSuccess: props<{ item: Update<{ id: number; name: string; }> }>(),
failure: props<{ error: string }>(),
},
});
This is my reducer stuff:
export interface ItemsState extends EntityState<{ id: number; name: string; }> {
selectedId?: string | number | null;
loaded: boolean;
error?: string | null;
}
export interface ItemsPartialState {
readonly [ITEMS_FEATURE_KEY]: ItemsState;
}
export const itemsAdapter: EntityAdapter<{ id: number; name: string; }> = createEntityAdapter<{ id: number; name: string; }>();
export const initialItemsState: ItemsState = itemsAdapter.getInitialState({
loaded: false,
});
const reducer = createReducer(
initialItemsState,
on(ItemsActions.updateItem, (state) => ({
...state,
loaded: false,
error: null,
})),
on(ItemsActions.updateItemSuccess, (state, { item }) => {
// Yea! Currently item type is { id: number; name: string; }
// And that doesn't work with updateOne method.
return itemsAdapter.updateOne(item, {
...state,
loaded: true,
error: null,
});
}),
);
Any help would be appreciated. Thanks.
updateOne
and updateMany
want you to specify id
and changes
.
Here the docs: Entity Updates.
So your code will be:
on(ItemsActions.updateItemSuccess, (state, { item }) => {
return itemsAdapter.updateOne(
{ id: item.id, changes: item },
{ ...state, loaded: true, error: null }
);
}),