Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

265
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda