-
Notifications
You must be signed in to change notification settings - Fork 41
Description
Usually, we don't want to define details of the underlying HTTP call in the store. It's more usual to move this into a service:
readonly save() {
return httpMutation<Flight, Flight>( (flight) => ({
url: 'https://...',
method: 'POST',
body: flight,
}));
}
However, the store needs to be able to specify the success
and error
handlers, as well as the flattening operator
to use. To streamline this task, this RFC proposes a builder-like style for specifying these details via setters in the store:
withMutations((store) => ({
save: store._flightService.save()
.withOnSuccess: (result: Flight) => {
patchState(store, { flightValue: result });
store._snackBar.open('Flight saved!', 'OK');
}
.withOnError: (error: any) => {
console.error('Error saving flight:', error);
store._snackBar.open('Error saving flight', 'OK');
},
.withOperator(mergeOp),
}),
),
Alternative
Providing types that expose all mutation options but the operation
(rxMutation) or request
(httpMutation) so that the caller can pass these options to the service:
export type MutationSettings<Params, Result> = Omit<
HttpMutationOptions<Params, Result>,
'request'
>;
In this case, the service method can be configured by the caller:
createSaveMutation(options: MutationSettings<Flight, Flight>) {
return httpMutation({
...options,
request: (flight) => ({
url: 'https://demo.angulararchitects.io/api/flight',
method: 'POST',
body: flight,
}),
});
}
In the store, such a method could be called as follows:
withMutations((store) => ({
save: store._flightService.createSaveMutation({
onSuccess: (result: Flight) => {
patchState(store, { flightValue: result });
store._snackBar.open('Flight saved!', 'OK');
},
onError: (error: any) => {
console.error('Error saving flight:', error);
store._snackBar.open('Error saving flight', 'OK');
},
}),
})),
One disadvantage of this solution is that it adds one more level of nesting when calling the service method.