【问题标题】:Modifying a http response using RXJS使用 RXJS 修改 http 响应
【发布时间】:2021-01-01 01:55:13
【问题描述】:

我有一个返回此示例有效负载的 API -

    {
      "uid": "string",
      "queue": {
        "size": 0,
        "averageWaitTime": 0,
        "inChair": "string",
        "status": "OPEN",
        "customers": [
          {
            "uid": "1b3",
            "haircut": "SHAPE_UP",
            "hasBeard": true,
            "useScissors": true
          },
          {
            "uid": "1b2",
            "haircut": "SHAPE_UP",
            "hasBeard": true,
            "useScissors": true
          }
        ]
      }
    }

在将响应返回给调用函数之前,我需要做的是遍历客户 [] 并使用数组的每个对象中的“uid”值发出进一步的 HTTP 请求,以获得需要附加的额外数据到其各自的对象。所以它看起来像这样 -

{
      "uid": "string",
      "queue": {
        "size": 0,
        "averageWaitTime": 0,
        "inChair": "string",
        "status": "OPEN",
        "customers": [
          {
            "uid": "1b3",
            "haircut": "SHAPE_UP",
            "hasBeard": true,
            "useScissors": true,
            "extra": {
                "name": "Fred",
                "telephone": "000"
            }
          },
          {
            "uid": "1b2",
            "haircut": "SHAPE_UP",
            "hasBeard": true,
            "useScissors": true,
            "extra": {
                "name": "Fred",
                "telephone": "000"
            }
          }
        ]
      }
    }

这是我迄今为止尝试过的 -

barberQueue(): Observable<BarberConfigurations> {
        return this.http.get<BarberConfigurations>( `${environment.apiEndpoint}/barber/profile` )
        .pipe(
            mergeMap( ( response: any ) => {
                return forkJoin(
                    response.queue.customers.map( customer => {
                        return this.customerService.get( customer.uid ).pipe(
                            map( resp => {
                                return {
                                    ...customer,
                                    extra: resp
                                };
                            } )
                        );
                    } )
                );
            } ),
        );
    }

这只是返回一个 [] 的客户对象。我需要的仍然是以正确的结构返回原始有效负载的其余部分。我不认为我对一些运营商有足够的了解。

有人可以帮助我了解我哪里出错了吗?

【问题讨论】:

标签: angular rxjs observable


【解决方案1】:

您只需要在 mergeMap 的帮助下为每个客户返回一个新的 observable

    return this.http.get<BarberConfigurations>( `${environment.apiEndpoint}/barber/profile` )
    .pipe(mergeMap(customer => this.customerService.get( customer.uid )
    .pipe(map( resp => {
                            return {
                                ...customer,
                                queue: {
                                  customers: customer.queue.customers.map(c => ({...c, extra: resp}))
                                }
                                
                            };
                        }), take(1)  ) ));

【讨论】:

  • 客户存在于客户 [] 中,那么我如何通过 mergeMap 反映这一点?
  • 可能是我理解错了,this.http.get&lt;BarberConfigurations&gt;( ${environment.apiEndpoint}/barber/profile ) 返回的是什么
  • 您尝试过这种方法吗?你有什么错误吗?
  • 它返回我的问题中的第一个对象示例
【解决方案2】:

我认为你已经完成了 99% 的工作。您已经用额外的数据丰富了客户,现在您只需要一个步骤将丰富的数组重新插入到您的原始负载中。

function barberQueue(): Observable<any> {

  return this.http.get<BarberConfigurations>(
    `${environment.apiEndpoint}/barber/profile`
  ).pipe(
    mergeMap(barbConfig => 
      forkJoin(
        barbConfig.queue.customers.map(customer =>
          this.customerService.get( customer.uid ).pipe(
            map(resp => ({
              ...customer,
              extra: resp
            }))
          )
        )
      ).pipe(
        map(customers => {
          barbConfig.queue.customers = customers
          return barbConfig;
        })
      )
    )
  );

}

你也可以分离出一些逻辑,让你的代码更清晰一点

function barberQueue(): Observable<any> {

  const enrichCustomerService = customer =>
    this.customerService.get( customer.uid ).pipe(
      map(resp => ({
        ...customer,
        extra: resp
      }))
    );

  const enrichPayload = config => customers => {
    config.queue.customers = customers
    return config;
  }

  return this.http.get<BarberConfigurations>(
    `${environment.apiEndpoint}/barber/profile`
  ).pipe(
    mergeMap(barbConfig => 
      forkJoin(
        barbConfig.queue.customers.map(enrichCustomerService)
      ).pipe(
        map(enrichPayload(barbConfig))
      )
    )
  );

}

【讨论】:

    猜你喜欢
    • 2010-12-03
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多