Массив Observables запрашивает строку? - PullRequest
0 голосов
/ 17 мая 2019

Привет, я все еще экспериментирую с RxJS и пытаюсь для каждого Observables в массиве восстановить связанное изображение этого Observable следующим образом:

  1. У меня есть массив наблюдаемых назначений
  2. Foreach Assignment получает свойство «Logo» (это идентификатор изображения) и, если оно имеет, получает свое изображение в виде строки (dataUrl)
  3. Возвращает все назначения со свойством Image в виде массива

Пока я сделал это:

public collectAssignements(): Observable<Observable<AssignementEntity>> {
    return this.assignementService.get('').pipe(
      map((assignments: AssignementEntity[]) => from(assignments.map((assignment) => new AssignementEntity(assignment))))
    );
  }

public assignements(): Observable<AssignementEntity[]> {
    return this.collectAssignements().pipe(
      mergeMap((assignment: Observable<AssignementEntity>) => {
        return assignment;
      }),
      map((assignment: AssignementEntity) => {
        return assignment;
      }),
      // here I'd like to use my function getPhoto on assignment.Platform.Logo if there is one (Logo is an Id)
      // then set the retreived string (dataUrl) to assignment.Platform.Image
      // but I can't figure out how to do that?
      toArray()
    )
  }

Чтобы получить мое изображение из моего задания, я должен передать идентификатор фотографии (здесь assignment.Platform.Logo) в getPhoto здесь, который возвращает наблюдаемую строку:

public fileReader(blob: Blob): Observable<string> { // @todo inclure le FileReaderService readAsDataURL
    return Observable.create((obs: Observer<string | ArrayBuffer>) => {
      const reader = new FileReader();

      reader.onerror = err => obs.error(err);
      reader.onabort = err => obs.error(err);
      reader.onload = () => obs.next(reader.result);
      reader.onloadend = () => obs.complete();

      return reader.readAsDataURL(blob);
    });
  }


  public getPhoto(id: string, size: string = "min"): Observable<string> {
    return this.httpClient.get(`${this.environment.get('webServiceUrl')}/photos/${id}/${this.endpoint.slice(0, -1)}/${size}`, { responseType: "blob" as "json" }).pipe(
      mergeMap((blob: Blob) => this.fileReader(blob))
    );
  }

При получении assignmentService возвращается Observable<Assignment[]>, а AssignmentEntity имеет Platform (сущность) со свойством Logo (это Id со строкой). Более того, у сущности Platform свойство (строка) Image по умолчанию пустое, ожидая заполнения dataUrl.

1 Ответ

1 голос
/ 17 мая 2019

После борьбы с документацией по RxJS я пришел к такому решению:

public assignements(): Observable<AssignementEntity[]> {
    return this.assignementService.get('').pipe(
      map((assignments: AssignementEntity[]) => from(assignments.map((assignment) => new AssignementEntity(assignment)))),
      mergeMap((assignment: Observable<AssignementEntity>) => {
        return assignment;
      }),
      map((assignment: AssignementEntity) => {
        return assignment;
      }),
      mergeMap((assignment: AssignementEntity) => { // forEach assignment if it has a Logo then make a request to get the image
        return assignment.Platform.Logo !== null ? this.platformService.getPhoto(assignment.PlatformId).pipe(
          map((image: string) => {
            assignment.Platform.Image = image;
            return assignment;
          })
        ) : of(assignment); // return the base assignment if no logo
      }),
      toArray(), // convert to an array
    );
  }
...