Reputation: 10021
I have a method on a service where I need to get some data from the redux store and use it in an http request, but I keep getting errors or the http request is not executed, here' what I'm trying:
class SettingService {
updateSettings({ settings }) {
return this.store.select(s => s.settings).map((state: any) => {
const { id } = state.data;
return this.http.put('route/' + id, { settings }).pipe(map((response: any) => {
const { data } = response;
this.store.dispatch(new GetSettingsSuccess({ data }));
return data;
})).pipe(catchError(this.errorHandlerService.handleError));
});
}
}
Errors I'm getting are things like
Property 'map' does not exist on type 'Observable'
the way I'm using this is importing the service into a component, then:
this.settingService.updateSettings({ settings }).subscribe();
the method is called, but for some reason the http request doesn't happen. Am I supposed to subscribe to the http request too? or should I use pipe instead of map and give it multiple operators instead?
Upvotes: 2
Views: 1433
Reputation: 14139
You should chain multiple operators in a pipe
. Use switchMap
(or even mergeMap
) to map your store output to the Observable from the Http request and then do your other tasks each in its own operator. You get much cleaner code this way.
It should look something like this:
updateSettings({ settings }) {
return this.store.select(s => s.settings)
.pipe(
// map the state from your store to the http request
switchMap((state: any) => this.http.put('route/' + state.data.id, { settings })),
// map the http response to the data your care about
map((response: any) => response.data),
// execute any other task with that data
tap(data => this.store.dispatch(new GetSettingsSuccess({ data }))),
// catch errors if they occurr
catchError(this.errorHandlerService.handleError),
);
You then subscribe to the returned Observable and your http request will be executed after a value from the store is emitted.
this.settingService.updateSettings({ settings }).subscribe(
// you'll have access to your data from the http response here
data => doSomething(data)
);
Upvotes: 3
Reputation: 5289
Here's a Pseudo code for what you might want to try:
updateSettings({ settings }) {
// use store select through a reducer:
return this.store.select('your_reducer_here').subscribe( state => {
//get id from your state
const id = state.data;
//use that id in your http call
return this.http.put('route/' + id, { settings }).pipe(map((response: any) => {
const { data } = response;
this.store.dispatch(new GetSettingsSuccess({ data }));
return data;
})).pipe(catchError(this.errorHandlerService.handleError));
});
})
}
Upvotes: 1
Reputation: 2374
You call map on a observable here this.store.select(s => s.settings).map((state: any)
You need to use a pipe(map())
. In this line you do it right: return this.http.put('route/' + id, { settings }).pipe(map((response: any)
Upvotes: 1