Заставьте Angular распознаватель ждать изображения - PullRequest
0 голосов
/ 05 марта 2020

Что можно сделать, чтобы резолвер подождал, пока он не получит изображения из API. Прямо сейчас, Angular ждет получения данных, показывает страницу и затем пытается получить изображения сообщения.

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      map(response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(image => {
            this.API.getImageById(image.id).subscribe(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );
  }
}

Ответы [ 2 ]

2 голосов
/ 05 марта 2020

Попробуйте:

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      switchMap(response => { // change this into a switchMap
        if (response["images"]) {
          return combineLatest(
            // combine all of the request for the images
            ...response["images"].map(image => this.API.getImageById(image.id)),
          ).pipe(
            map(images => images.map(image => ({ url: window.URL.createObjectURL(image) })),
            map(images => ({ response: images })), // This map may be unnecessary
          );
        } else {
         return of([]);
        }
      })
    );
  }
}

Это должно начать вас. Проблема с вашим подходом заключается в том, что вы подписываетесь во внутреннюю наблюдаемую область, и я не думаю, что средство распознавания маршрута ждет этого.

0 голосов
/ 05 марта 2020

Вы возвращаете «ответ» перед разрешением асинхронного метода «this.API.getImageById (image.id)». Вы должны дождаться окончания всех асинхронных итераций, прежде чем вернуться. Есть несколько вариантов, чтобы сделать это, это на вариант:

return this.API.getPostById(route.params.id).pipe(
      map(async response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(image => {
           await this.API.getImageById(image.id).then(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );
...