Home > Back-end >  How can I NOT wait for both observables to come and use data of 1 observable in swtichmap?
How can I NOT wait for both observables to come and use data of 1 observable in swtichmap?

Time:08-24

In this code below , I want student list to be rendered immediately and not wait for the second observable , but when second observable comes , it should check that student is not enrolled in all courses and then enable the button to add to course.

enter image description here

enter image description here

enter image description here

CodePudding user response:

You need to first create a behaviour subject, the special property of behaviour subject is we can have a initialization value. Then when each api call completes we can update the subject with the latest value.

Learn more about behaviour subject

html

<div >
  <div  *ngIf="studentDataSubject | async as studentData">
    <div *ngFor="let student of studentData">
      <div>{{ student.name }}</div>
      <button  [disabled]="student.enable">Add to course</button>
    </div>
  </div>

  <div  *ngIf="courseDataList | async as courseData">
    <div *ngFor="let course of courseData">
      <div>{{ course.name }}</div>
    </div>
  </div>
</div>

ts

import { Component, OnInit, VERSION } from '@angular/core';
import { BehaviorSubject, map, Observable, switchMap, tap } from 'rxjs';
import {
  IStudentData,
  getStudentList,
  ICourseData,
  getCourseList,
} from './dummyApi';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  studentDataSubject: BehaviorSubject<any> = new BehaviorSubject<any>([]);
  name = 'Angular '   VERSION.major;

  studentDataList: Observable<IStudentData[]> = getStudentList(); // no delay
  courseDataList: Observable<ICourseData[]> = getCourseList(); // data comes after 3 seconds

  ngOnInit() {
    this.studentDataList
      .pipe(
        switchMap((studentData) => {
          this.studentDataSubject.next(studentData);
          return this.courseDataList.pipe(
            tap((courseData) => {
              const newStudentData = studentData.map((student) => {
                let dummyStudentObj = {
                  ...student,
                  enable: student.courseCount < courseData.length,
                };
                return dummyStudentObj;
              });
              this.studentDataSubject.next(newStudentData);
            })
          );
        })
      )
      .subscribe();
  }
}

forked stackblitz

  • Related