如何从2个http请求中以角度构建单个对象,而不添加另一个值

时间:2019-04-18 15:40:23

标签: angular rxjs

如果您查看此question。这个问题确实很简单,但是解决方案却更加复杂,以解决更多细节,我在问这个问题。

如果您正在使用stackblitz,则代码会尝试在将对象传递给组件之前先构建对象。我遇到的问题是代码添加的键值,它破坏了formcontrols。

第一个响应返回带有仅具有这些值的路由的对象。

      addressPointId: "adress",
      municipalityId: "municipallyty",
      regionId: "regionId",
      settlementId: "settlementId",
      rvId: "rvId", // <---  not included in second call getAddressPoint 
      sequenceNumber: "sequenceNumber" // <---  not included in second call getAddressPoint 

第二个http请求采用这些值,并以名称值返回,但不包括rvId和sequenceNumber。

    addressPointId: "adress",
    municipalityId: "municipallyty",
    regionId: "regionId",
    settlementId: "settlementId",
    regionName: "regionName", // <---  this is added 
    municipalityName: "municipalityName", // <---  this is added
    settlementName: "settlementName", // <---  this is added
    description: "description",

我要获取结果对象。

{ <-- coming from first request getRequest
     "statusId": 1,
     "recDate": "2019-04-18T11:05:25.827Z",
     "requestVehicles": [
         {
             "garageId": 1,
             "routes": [
                 {
                     "addressPointId": "dasdad", // <-- is in both
                     "municipalityId": 34, // <-- is in both
                     "regionId": 4, // <-- is in both
                     "rvId": "",  // <-- coming from first request getRequest
                     "sequenceNumber": "", // <-- coming from first request getRequest
                     "settlementId": null, // <-- is in both
                     "regionName": "dasd", // <-- coming from second request getAddressPoint
                     "municipalityName": "dasdasd", // <-- coming from second request getAddressPoint
                     "settlementName": null, // <-- coming from second request getAddressPoint
                     "description": "Nadaburi" // <-- coming from second request getAddressPoint
                 } 
             ],
         }
     ],
 }

(不幸的是无法修复stackblitz),现在我在我的实际项目中得到了它:

{ <-- coming from first request getRequest
     "statusId": 1,
     "recDate": "2019-04-18T11:05:25.827Z",
     "requestVehicles": [
         {
             "garageId": 1,
             "routes": [
                 { // =================================
                     "key": { key object } // <========== this breaks the fromcontrols
//============================================================
                     "addressPointId": "dasdad", // <-- is in both
                     "municipalityId": 34, // <-- is in both
                     "regionId": 4, // <-- is in both
                     "rvId": "",  // <-- coming from first request getRequest
                     "sequenceNumber": "", // <-- coming from first request getRequest
                     "settlementId": null, // <-- is in both
                     "regionName": "dasd", // <-- coming from second request getAddressPoint
                     "municipalityName": "dasdasd", // <-- coming from second request getAddressPoint
                     "settlementName": null, // <-- coming from second request getAddressPoint
                     "description": "Nadaburi" // <-- coming from second request getAddressPoint
                 } 
             ],
         }
     ],
 }

原始代码来自stackblitz.。我根据实际情况进行了更改。

由于某种原因,新的stackblitz没有运行,但它对我的实际项目正常,除了响应中有额外的键值。

2 个答案:

答案 0 :(得分:0)

我认为您可以使用RxJ combineLast来实现所需的功能。

如果您将第一个调用和下一个调用的结果与combineLast组合在一起,将可以订阅并获取两个对象,并返回它们的组合。

这是一个例子:

const objA = {xpto: 'xis'};
const objB = {moreData: 'pato'};


of(objA).pipe(
  map((a) => {
    return combineLatest(of(a), of(objB));
  })
).subscribe((result) => {
  result.pipe(
    map(([a, b]) => {
      return {
        newXpto: a.xpto,
        newMoreData: b.moreData
      };
    })
  ).subscribe((combinedObjects) => {
    console.log(combinedObjects);
   })
})

类似的事情应该起作用。我不知道这是否是更合理的答案,但我很快就做了。不过,它使您对如何做到这一点有所了解。

答案 1 :(得分:0)

如果我正确理解了您的问题,则似乎是您在询问一个本身依赖于另一个请求的http请求,并且需要以某种方式将这两个请求组合在一起以创建您想要的对象利用。如果我正确,那么这里有一些可行的示例。

首先,您可以在调用本身(即component.ts文件中)中构建所需的对象

const id = this.getIdFromRoute(this.route, 'customerId');

let customerWithSource: ICustomer;

this.customerService.getById(id)
    .subscribe((customer) => {
        this.customerSourceService.getById(customer.SourceId)
            .subscribe((source) => {
                customerWithSource = customer;
                customerWithSource.CustomerSource = source;
            });
        });

或者您可以在服务中执行此操作,这样您就可以在组件中订阅已经为您完成所有工作的方法。如果您要重用,那就太好了。

    getCustomerWithSource(id: number): Observable<ICustomer> {
        return this.getById(id).pipe(
            concatMap((customer) => {
                return this.customerSourceService
                    .getById(customer.SourceId)
                    .pipe(
                        map((source) => {
                            customer.CustomerSource = source;
                            return customer;
                        }),
                    );
            }),
        );
    }

第二个方法的工作方式是返回第一个答案,然后使用concatMap使用第一个调用的值进行第二个调用,然后最后使用map生成最终对象并返回它。 / p>