1
votes

Angular - comment obtenir l'état de ngrx puis effectuer http

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?


2 commentaires

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?


3 Réponses :


1
votes

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)


0 commentaires

1
votes

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));
    });
    })
}


1 commentaires

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.



2
votes

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),   
    );


0 commentaires