0

I'm working in a Backend For Frontend (BFF) that receive a request by front end, the bff request an another api and with responses, creates the object to return to front end.

I would like to know if i'm using promises and await call correctly, there are two situations:

const [affiliates, { content }]: [
  { content: AffiliateType[] },
  IManagerTypeList,
] = await Promise.all([
  await this.affiliatesService.getAffiliates(
    { clientId: client?.id },
  ),
  await this.managersService.getManagers(
    { clientId: client?.id },
  ),
])

getAffiliates and getManagers are async methods that call another api. The content const i return directly to front end. With affiliates, i do the follow:

const unresolvedTransformedAffiliateToReturn = affiliates.content.map(
  async (affiliate): Promise<AffiliateType> => {
    const addressInfo: AddressType =
      await this.addressService.getAddressesById(
        affiliate.addressId,
      )

    const managerInfo: ManagersType =
      await this.managersService.getManagers(
        affiliate.managerId,
      )

    return {
      id: affiliate.id,
      name: affiliate.name,
      clientId: affiliate.clientId,
      managerId: affiliate.managerId,
      addressId: affiliate.addressId,
      address: addressInfo,
      manager: managerInfo,
    }
  },
)

const transformedAffiliateToReturn = await Promise.all(
  unresolvedTransformedAffiliateToReturn,
)

What is going here. affiliates.content is a array of object. I need to use some variables of affiliate to call getAddressesById and getManagers endpoints (also asyncs), like addressInfo and managerInfo, then, use this return to return to front end.

The final return to front end is:

{
  managers: content,
  affiliates: transformedAffiliateToReturn,
}

All works correctly. I'm only wondering if it's the right way to use promise.all and async/wait functions.

Some opinions or suggestions will be appreciate. Thanks!

EDIT: Example of getAffiliates request:

getAffiliates<R>(id: number, api?: string): Promise<R> {
  return this.customHttpService.mountRequest(
    RequestTypeEnum.GET,
    `/endpoint/${id}`,
    null,
    null,
    null,
    api,
    true,
)

}

mountRequest scope:

async mountRequest<P, B, H, R>(
  requestType: RequestTypeEnum,
  endpoint: string,
  params?: P,
  body?: B,
  headers?: H,
  api?: string,
  ignoreNotFoundError?: boolean,
  ): Promise<R> {
    const defaultApi: string = api ? api : 
    let request: Observable<AxiosResponse<R>>
    ...
  }
)
RAFAEL DA SILVA
  • 99
  • 2
  • 11
  • you can learn about `async/await` here: https://javascript.info/async-await – Micael Levi Mar 16 '22 at 20:21
  • You don't need to await in a `Promise.all(...)`. The results would automatically be resolved. Instead of awaiting in parallel, you actually made it run in series because you await it like that – xxMrPHDxx Mar 16 '22 at 20:24
  • If i don't await in Promise.all, i got this typescript error. Type 'Promise' is missing the following properties from type 'AffiliateType[]': length, pop, push, concat, and 29 more. – RAFAEL DA SILVA Mar 16 '22 at 20:32
  • or if a use ```unresolvedTransformedAffiliateToReturn``` instead of ```transformedAffiliateToReturn``` directly in return, i got this: Type 'Promise[]' is not assignable to type 'AffiliateType[]'. Type 'Promise' is missing the following properties from type 'AffiliateType': id, name, managerId, address, addressId – RAFAEL DA SILVA Mar 16 '22 at 20:34
  • Looks like `getAffiliates` and `getManager` return a Promise of Promise. You can definitely refactor that – xxMrPHDxx Mar 16 '22 at 22:52
  • Could be. added examples of ```getAffiliates``` in main question. This piece of code was in project when i started. – RAFAEL DA SILVA Mar 16 '22 at 23:15

0 Answers0