J'ai une méthode sur un service où j'ai besoin d'obtenir des données du magasin redux et de les utiliser dans une requête http, mais j'obtiens toujours des erreurs La requête http n'est pas exécutée, voici ce que j'essaye:
this.settingService.updateSettings({ settings }).subscribe();
Les erreurs que j'obtiens sont des choses comme
La propriété 'map' n'existe pas sur le type 'Observable'
la façon dont j'utilise ceci importe le service dans un composant, puis:
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)); }); } }
la méthode est appelée, mais pour une raison quelconque, le http la demande ne se produit pas. Suis-je censé m'abonner également à la requête http? ou devrais-je utiliser pipe au lieu de map et lui donner plusieurs opérateurs à la place?
3 Réponses :
Vous appelez map sur un observable ici this.store.select (s => s.settings) .map ((state: any)
Vous devez utiliser un tube (map ( ))
. Dans cette ligne, vous le faites correctement: retournez this.http.put ('route /' + id, {settings}). pipe (map ((response: any)
Voici un pseudo-code pour ce que vous pourriez vouloir essayer:
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)); }); }) }
Cela ne fonctionnera pas. Vous ne vous abonnez jamais à la requête http donc elle ne sera pas exécutée. Notez que retourner quelque chose dans un abonnement
ne fait rien.
Vous devez enchaîner plusieurs opérateurs dans un tube
. Utilisez switchMap
(ou même mergeMap
) pour mapper la sortie de votre magasin à l'Observable à partir de la requête Http, puis effectuez vos autres tâches chacune dans son propre opérateur. Vous obtenez un code beaucoup plus propre de cette façon.
Cela devrait ressembler à ceci:
this.settingService.updateSettings({ settings }).subscribe( // you'll have access to your data from the http response here data => doSomething(data) );
Vous vous abonnez alors à l'Observable retourné et votre requête http sera exécutée après une valeur du magasin est émis.
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), );
Oui, vous êtes censé vous abonner à votre appel http, le mappage ne suffit pas.
@Korfoo alors comment puis-je m'abonner à partir du composant à la méthode de service 1 fois et que le sélecteur ngrx et le http fonctionnent tous les deux ensemble?