Angular-如何从ngrx获取状态然后执行http

时间:2019-01-15 15:53:28

标签: angular ngrx ngrx-store

我在服务上有一种方法,我需要从redux存储中获取一些数据并在http请求中使用它,但是在 http请求未执行,这是我正在尝试的内容:

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

我遇到的错误是

  

“可观察”类型上不存在“地图”

我使用此方法的方式是将服务导入组件,然后:

this.settingService.updateSettings({ settings }).subscribe();

该方法被调用,但是由于某种原因,http请求没有发生。我也应该订阅http请求吗?还是应该使用管道而不是地图,而是给它多个运算符?

3 个答案:

答案 0 :(得分:2)

以下是您可能想要尝试的伪代码:

 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 :(得分:2)

您应该在pipe中链接多个运算符。使用switchMap(或什至mergeMap)将您的商店输出映射到Http请求中的Observable,然后在其自己的运算符中分别执行其他任务。这样您将获得更简洁的代码。

它应该看起来像这样:

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

然后,您预订返回的Observable,并在发出存储中的值之后执行您的http请求。

this.settingService.updateSettings({ settings }).subscribe(
  // you'll have access to your data from the http response here
  data => doSomething(data) 
);

答案 2 :(得分:1)

您在此处的this.store.select(s => s.settings).map((state: any)上调用一个可观察图。在这一行中,您可以正确执行此操作:pipe(map())