Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

266
Visualizações
Angular: How to get value from an observable inside another observable

I am fetching data from API that return a array of objects. Each object contains a link to which I have to make a GET request again to get the final result. This is how I have implemented this.

return this.client.request(new HttpRequest("GET", request, {
  headers: new HttpHeaders({
    Authorization: `bearer ${environment.vimeoConfig.accesstoken}`
  })
})).pipe(
  filter((response) => {
    return response instanceof HttpResponse
  }),
  tap((res: HttpResponse < any > ) => {
    pagingQuery.maxpages = (res.body.total / batchSize);
    if (pagingQuery.maxpages % 1 > 0) pagingQuery.maxpages = Math.floor(pagingQuery.maxpages) + 1
    pagingQuery.page++;
  }),
  map((res: HttpResponse < any > ) => (res.body.data as any[]).map((data) => {

    return {
      id: data.uri.split('/')[2],
      title: data.name,
      desc: data.description,
      date: data.created_time,
      thumbid: "",
      durationInSeconds: data.duration,
      links: new Map(data.files.map(file => [file.height ? ? 'hls', file.link])),
      videoObservable: this.client.get(`https://api.vimeo.com${data.pictures.uri}?sizes=96x54`, {
        headers: new HttpHeaders({
          Authorization: `bearer ${environment.vimeoConfig.accesstoken}`
        })
      })
    }
    as VimeoVid;
  }))
)

So I am returning the observable for each object.

In the HTML I am doing the following

<mat-list-option class="option" *ngFor="let vid of vids" [value]="vid">
  <mat-radio-button color="primary" [checked]="_selectedVid === vid"></mat-radio-button>
  <ng-container *ngIf="vid.videoObservable | async as thumb else optionSkeleton">
    <img [src]="thumb.sizes[0].link">
  </ng-container>
  <div class="vid-title sub1">{{vid.title}}</div>
  <div class="sub1">Private link</div>
  <div class="sub1">{{format(vid.date)}}</div>
</mat-list-option>

I know this is not the way to do this. What is a better way to implement this?

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

I have not tested it but it could be this way. I have used property video instead of videoObservable, also make sure you don't use async pipe in template.

First, let's divide our code into doPageCalc, getVideos

return this.client.request(new HttpRequest("GET", request, {
  headers: new HttpHeaders({
    Authorization: `bearer ${environment.vimeoConfig.accesstoken}`
  })
})).pipe(
  filter(response => response instanceof HttpResponse),
  tap((res: HttpResponse < any > ) => this.doPageCalc(res)),
  map((res: HttpResponse < any > ) => this.getVideos(res))
);

doPageCalc(res: HttpResponse < any >): any{
    pagingQuery.maxpages = (res.body.total / batchSize);
    if (pagingQuery.maxpages % 1 > 0) pagingQuery.maxpages = Math.floor(pagingQuery.maxpages) + 1
    pagingQuery.page++;
}

getVideos(res: HttpResponse < any >): Observable<VimeoVid[]>{
    const bodyData = res.body.data as any[];
    
    // create stream from of each data
    return from(bodyData).pipe(
        // run in parallel for each bodyData
        mergeMap(data => of(data).pipe(
                // switch to get video
                switchMap(d => this.getVideo(d)),
                // combine video metaData with actual video data
                map(video => ({ ...this.getVideoMeta(data), video } as VimeoVid))
            )
        ),
        toArray()
    );
}

getVideo(data: any): Observable<any>{
    this.client.get(`https://api.vimeo.com${data.pictures.uri}?sizes=96x54`, {
        headers: new HttpHeaders({
          Authorization: `bearer ${environment.vimeoConfig.accesstoken}`
        })
      });
}

getVideoMeta(data: any): any{
    return {
        id: data.uri.split('/')[2],
        title: data.name,
        desc: data.description,
        date: data.created_time,
        thumbid: "",
        durationInSeconds: data.duration,
        links: new Map(data.files.map(file => [file.height ? ? 'hls', file.link]))
    };
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda