【问题标题】:Angular - how to get state from ngrx and then perform httpAngular - 如何从ngrx获取状态然后执行http
【发布时间】:2019-01-15 15:53:27
【问题描述】:

我在服务上有一个方法,我需要从 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请求吗?或者我应该使用管道而不是地图并给它多个运算符?

【问题讨论】:

  • 是的,你应该订阅你的 http 调用,仅仅映射是不够的。
  • @Korfoo 那么我如何从组件订阅服务方法 1 次并且 ngrx 选择器和 http 都一起运行?

标签: angular ngrx ngrx-store


【解决方案1】:

您应该在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】:

    您在此处的可观察对象上调用 map this.store.select(s => s.settings).map((state: any) 您需要使用 pipe(map())。在这一行中你做对了:return this.http.put('route/' + id, { settings }).pipe(map((response: any)

    【讨论】:

      【解决方案3】:

      这是您可能想尝试的伪代码:

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

      【讨论】:

      • 这行不通。您永远不会订阅 http 请求,因此它不会被执行。请注意,在 subscribe 中返回某些内容不会执行任何操作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      • 2021-08-07
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      相关资源
      最近更新 更多