Я пытаюсь использовать async / await для получения службы, но вторая служба возвращает не заполнить мои переменные - PullRequest
1 голос
/ 18 июня 2019

У меня есть сервис для получения списка с сервера. Но в этом списке мне нужно позвонить в другую службу, чтобы вернуть логотип img, служба вернулась нормально, но мой список остается пустым. Что я не так сделал?

Я пытался использовать async / await в обоих сервисах Я попытался использовать отдельную функцию, чтобы получить логотипы позже, но мой HTML не изменился.

 async getOpportunitiesByPage(_searchQueryAdvanced: any = 'active:true') {
    this.listaOportunidades = await this._opportunities
      .listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced)
      .toPromise()
      .then(result => {
        this.totalSize = result['totalElements'];
        return result['content'].map(async (opportunities: any) => {
          opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
          console.log(opportunities.logoDesktopUrl);
          return { opportunities };
        });
      });

    this.getTasks(this.totalSize);
  }

Без ошибок, только мой HTML не меняется. в моем console.log (opportunities.logoDesktopUrl); возврат не определен

но в конце возвращение заполнено.

информация: Угловой 7 сервер amazon aws.

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Сначала, когда вы await, вы не должны использовать then.

В секунду async/await работает только с Обещаниями.

async getOpportunitiesByPage(_searchQueryAdvanced: any = 'active:true') {
  const result = await this._opportunities
    .listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced)
    .toPromise();
  this.totalSize = result['totalElements'];
  this.listaOportunidades = result['content'].map(async (opportunities: any) => {
    opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']);
    console.log(opportunities.logoDesktopUrl);
    return opportunities;
  });

  this.getTasks(this.totalSize);
}

getBrand(brandsUuid) { 
  return new Promise((resolve, reject) => {
    this.brandService.getById(brandsUuid).subscribe(res => { 
      console.log(res.logoDesktopUrl);
      return resolve(res.logoDesktopUrl);
    }, err => {
      return reject(err);
    });
  });
}

Но, поскольку rxjs используется в Angular, вы должны использовать его вместо async/await:

getOpportunitiesByPage: void(_searchQueryAdanced: any = 'active:true') {
  this._opportunities.listaOportunidades(this.pageSize, this.currentPage, _searchQueryAdvanced).pipe(
    tap(result => {
      // we do that here because the original result will be "lost" after the next 'flatMap' operation
      this.totalSize = result['totalElements'];
    }),
    // first, we create an array of observables then flatten it with flatMap
    flatMap(result => result['content'].map(opportunities => this.getBrand(opportunities['brandsUuid']).pipe(
        // merge logoDesktopUrl into opportunities object
        map(logoDesktopUrl => ({...opportunities, ...{logoDesktopUrl}}))
      )
    ),
    // then we make each observable of flattened array complete
    mergeAll(),
    // then we wait for each observable to complete and push each result in an array
    toArray()
  ).subscribe(
    opportunitiesWithLogoUrl => { 
      this.listaOportunidades = opportunitiesWithLogoUrl;
      this.getTasks(this.totalSize);
    }, err => console.log(err)
  );
}

getBrand(brandsUuid): Observable<string> {
  return this.brandService.getById(brandsUuid).pipe(
    map(res => res.logoDesktopUrl)
  );
}

Вот рабочий пример stackblittz

Возможно, есть более простой способ сделать это, но он работает: -)

0 голосов
/ 18 июня 2019

await используется для ожидания promise.

Вы должны вернуть promise из getBrand, если хотите дождаться его в getOpportunitiesByPage.

Измените функцию getBrand следующим образом.

getBrand(brandsUuid): Observable<string> {
  this.brandService.getById(brandsUuid).pipe(map(res => { 
    console.log(res.logoDesktopUrl); return res.logoDesktopUrl;
  }))
}

Изменить opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']); на opportunities.logoDesktopUrl = await this.getBrand(opportunities['brandsUuid']).toPromise();

Пожалуйста, убедитесь, что вы импортировали map из rxjs/operators.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...