Angular 等待多个链接请求,然后发出最终的 POST 请求

问题描述 投票:0回答:1

该页面是创建企业及其1个或多个设施的表单。 每个机构都有一个地址。 我必须保存这一切。

所以我必须循环所有机构来保存其地址,然后将后端发送的addressId放入EnterpriseRequestModel中,然后保存企业。

我不知道如何做到这一点,我想这是 ForkJoin、MergeMap 等的某种组合,但我还不完全理解 RxJs 运算符,所以我需要一些帮助,谢谢。

[编辑]

好吧,现在该组件不支持多个设施,只有一个设施,保存所有这些的函数如下所示:

public onSave(): void {
this.isLoading = true;

const siren = this.entepriseWithEstablishmentFormGroup.controls.enterpriseFormGroup.controls.siren.value;
const enterprise = this.entepriseWithEstablishmentFormGroup.controls.enterpriseFormGroup.getRawValue();
const establishment = this.entepriseWithEstablishmentFormGroup.controls.establishmentFormGroup.getRawValue();
const siret = `${siren}${establishment.siret}`;
const establishmentRM = new EstablishmentRequestModel(establishment.name, siret, establishment.email, establishment.phone, null, establishment.addressId);
const enterpriseRM = new EnterpriseWithEstablishmentRequestModel(enterprise.name, enterprise.siren, establishmentRM);

this.isLoading = true;

// create enterprise and establishment in a row
this.subscriptions.add(
  this.enterpriseService
    .createEstablishmentAddress(this.addressFormGroup.getRawValue())
    .pipe(
      map((addressId) => addressId),
      catchError((error: HttpErrorResponse) =>
        throwError(() => {
          this.isLoading = false;
          this.toastr.error(this.translatePipe.transform('COMPANY.DIALOGS.CREATE.ERROR-MSG.PERSISTENCE-ERROR'), this.translatePipe.transform('ADDRESS.DIALOGS.CREATE.TITLE'));
        })
      ),
      switchMap((addressId) => {
        enterpriseRM.establishment.addressId = addressId;
        this.entepriseWithEstablishmentFormGroup.controls.establishmentFormGroup.controls.addressId.patchValue(addressId);
        //this.showAddressForm = false;
        return this.enterpriseService.createEnterpriseWithEstablishment(enterpriseRM).pipe(
          map((response) => response),
          catchError((error: HttpErrorResponse) =>
            throwError(() => {
              this.isLoading = false;
              this.toastr.error(this.translatePipe.transform('COMPANY.DIALOGS.CREATE.ERROR-MSG'), this.translatePipe.transform('COMPANY.DIALOGS.CREATE.TITLE'));
            })
          )
        );
      })
    )
    .subscribe((response) => {
      this.isLoading = false;

      if (response !== null) {
        this.dialogRef.close(response);
      }
    })
);

但如你所知,我现在必须为多个机构这样做。 保存地址的api和保存企业/机构的api是不同的。

基本上,我拥有的数据是这样的:

Enterprise : {
    socialReason: Apple;
    siren: 1248746392;
    establishment: [
      {
      name: Apple London;
      siret: 129838;
      addressId: null;
      enterpriseId: null;
      },
      { ...
    ]
}

如果没有addressId,我无法保存酒店。我明白你所说的让 ORM 管理对象,但它是这样完成的,我必须处理它..(而且我不是后端开发人员)

angular post rxjs
1个回答
0
投票

为了将来的参考,这是我找到并工作的答案:

public onSave(): void {
this.isLoading = true;

const enterpriseFormGroup = etc...;
const enterpriseRM = etc...;

this.enterpriseService.createEnterprise(enterpriseRM).subscribe((enterpriseId: number) => {
  if (enterpriseId) {
    this.saveEstablishments(enterpriseId);
  }
});
}

private saveEstablishments(enterpriseId: number): void {
const siren = siren.value;
const establishmentList = this.getEstablishmentList(siren);

const apiCall = (establishment: EstablishmentWithAddress) =>
  this.enterpriseService.createEstablishmentAddress(establishment.address).pipe(
    map((addressId) => addressId),
    catchError((error: HttpErrorResponse) =>
      throwError(() => {
        this.isLoading = false;
        this.toastr.error(...);
      })
    ),
    mergeMap((addressId: number) => {
      const establishmentRM = new EstablishmentRequestModel(addressId);
      return this.enterpriseService.createEstablishment(establishmentRM).pipe(
        map((response) => response),
        catchError((error: HttpErrorResponse) =>
          throwError(() => {
            this.isLoading = false;
            this.toastr.error(...);
          })
        )
      );
    })
  );

const apiCalls = Array.from(establishmentList, (v, i) => apiCall(v));
const numberOfSimultaneousRequests = 1;
let processedRows = 0;

this.subscriptions.add(
  of(...apiCalls)
    .pipe(mergeMap((savedData) => savedData, numberOfSimultaneousRequests))
    .subscribe({
      next: (savedData) => {
        processedRows++;
      },
      error: (err) => {
        console.log('error:', err);
      },
      complete: () => {
        if (processedRows === establishmentList.length) {
          this.isLoading = false;
          this.dialogRef.close({
            id: enterpriseId,
            establishmentId: null,
          });
        }
      },
    })
);
}

这个想法是创建一个函数调用数组(两个函数用 mergeMap、createAdress > createEstablished 链接起来)。然后用建立列表调用数组并用mergeMap执行数组。

开发起来真的很痛苦

© www.soinside.com 2019 - 2024. All rights reserved.