Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

267
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!