ngrx/signals call an rxMethod from an rxMethod #4576
-
Hello, I have an rxMethod in my signalStore that loads entities from my backend and patches it to my state. Upon a successful create request which is in another rxMethod, I would like to call that previous rxMethod i mentioned earlier. If I would use the original ngrx store i would make an effect for this (from @ngrx/effects pacakge), but in signals package I didn't find any way for this. The only way it worked for me is if I created another withMethods with the create rxMethod above the withMethods with the load rxMethod. Here is my signal store with the mentioned rxMethods import { patchState, signalStore, withMethods, withState } from "@ngrx/signals";
import { OrderConfirmation } from "../model/order-confirmation.model";
import { inject } from "@angular/core";
import { OrderConfirmationService } from "../services/order-confirmation.service";
import { NgxSpinnerService } from "ngx-spinner";
import { rxMethod } from "@ngrx/signals/rxjs-interop";
import { distinctUntilChanged, pipe, switchMap, tap } from "rxjs";
import { tapResponse } from "@ngrx/operators";
import { NzMessageService } from "ng-zorro-antd/message";
import { KuszaMessages } from "../../../constants/kusza-messages";
import { sortBy } from "lodash";
import { getQueryFilter } from "../../../helpers/filter.helper";
import { orderConfirmationFilterDefinition } from "../constants/order-confirmation.filter-definition";
import { withDevtools } from "@angular-architects/ngrx-toolkit";
type OrderConfirmationState = {
orderConfirmations: Array<OrderConfirmation>;
totalCount: number;
editedOrderConfirmation: OrderConfirmation | null;
};
const initialState: OrderConfirmationState = {
orderConfirmations: [],
totalCount: 0,
editedOrderConfirmation: null,
};
export const OrderConfirmationStore = signalStore(
withDevtools("orderConfirmations"),
withState(initialState),
withMethods(
(
store,
orderConfirmationService = inject(OrderConfirmationService),
spinner = inject(NgxSpinnerService),
) => ({
setEditedOrderConfirmation: (
editedOrderConfirmation?: OrderConfirmation,
) => patchState(store, { editedOrderConfirmation }),
clearEditedOrderConfirmation: () =>
patchState(store, { editedOrderConfirmation: null }),
getOrderConfirmations: () =>
sortBy(store.orderConfirmations(), ["orderConfirmationNumber"]),
loadOrderConfirmations: rxMethod<{ filter: Record<string, unknown> }>(
pipe(
distinctUntilChanged(),
tap(() => spinner.show()),
switchMap(({ filter }) => {
const { page, pageSize } = filter;
delete filter["page"];
delete filter["pageSize"];
const queryFilter = getQueryFilter(
filter,
orderConfirmationFilterDefinition,
);
return orderConfirmationService
.getOrderConfirmations(
{ currentPage: page as number, pageSize: pageSize as number },
queryFilter,
)
.pipe(
tapResponse({
next: ({ records, totalCount }) => {
patchState(store, {
orderConfirmations: records,
totalCount,
});
spinner.hide();
},
error: () => {
spinner.hide();
},
}),
);
}),
),
),
}),
),
withMethods(
(
store,
orderConfirmationService = inject(OrderConfirmationService),
spinner = inject(NgxSpinnerService),
message = inject(NzMessageService),
) => ({
saveOrderConfirmation: rxMethod<{
orderConfirmation: OrderConfirmation;
filter: Record<string, unknown>;
}>(
pipe(
tap(() => spinner.show()),
switchMap(({ orderConfirmation, filter }) =>
orderConfirmationService
.createOrderConfirmation(orderConfirmation)
.pipe(
tapResponse({
next: () => {
store.loadOrderConfirmations({ filter });
spinner.hide();
message.success(KuszaMessages.CREATED_SUCCESSFULLY);
},
error: () => {
spinner.hide();
},
}),
),
),
),
),
updateOrderConfirmation: rxMethod<{
orderConfirmation: OrderConfirmation;
filter: Record<string, unknown>;
}>(
pipe(
tap(() => spinner.show()),
switchMap(({ orderConfirmation, filter }) =>
orderConfirmationService
.updateOrderConfirmation(orderConfirmation)
.pipe(
tapResponse({
next: () => {
store.loadOrderConfirmations({ filter });
spinner.hide();
message.success(KuszaMessages.UPDATED_SUCCESSFULLY);
},
error: () => {
spinner.hide();
},
}),
),
),
),
),
}),
),
); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
Hey, do you maybe have a slimmed down version which shows only the actual problem. You could also post the ngrx/store solution with the effect |
Beta Was this translation helpful? Give feedback.
Why don't you just put the load method into the scope of
withMethods
? Like:Other than that, I'd highly recommend you to extract both functions into separate files. You don't want to have these pipes in the signalStore file.