devZ
devZ

Reputation: 726

Looping through data and displaying only last set of items in Angular

From the API I am fetching the list of categories with name and ID and then inside this list of categories I integrate the list of lectures from the second ID. This list of lectures must be different for every category (based on ID)

In my console.log() it works fine, but on the frontend I am somehow overwriting the allLectures array so that is the reason why in the frontend I get displayed only the lectures for the last category.

This lectures must be different for every category.

Typescript code:

  ngOnInit(): void {
      this.getCategories();   
  }


  getCategories() {
    this.categoryListSubs = this.categoryService
      .getAllCategories(this.limit, this.offset)
      .subscribe((categories: any) => {
        this.allDataFromApi = categories;
        this.categoryList = categories.results;
        this.isLoaded = true;

          this.categoryList.forEach((el: any) => {
          this.categoryID = el.id;
          this.getLectures(this.categoryID);
        });
      });
  }

  getLectures(id: any): void {
    console.log(id);

    this.isLoaded = false;

    this.allLecturesOfCategorySubs = this.categoryService
      .getLecturesOfCategory(id, this.limit, this.offset, this.queryParams.sort)
      .subscribe((allLectures: AllLecture) => {
        this.allLectures = allLectures.results;
        console.log(this.allLectures);

        this.isLoaded = true;
      });
  }
}

HTML code:

<div class="container mb-3 pt-5">
  <div class="categories" *ngFor="let category of categoryList">
    <div class="">
      <div class="d-flex mt-4 category-button py-1">
        <h2>
          {{ category.name }} <span>({{ category.lectures }})</span>
        </h2>
        <a
          class="btn rounded-full"
          [routerLink]="['/all-lectures']"
          [queryParams]="{ page: '1', sort: 'popularity' }"
        >
          All lectures <fa-icon [icon]="faArrowRight"></fa-icon>
        </a>
      </div>
      <div class="videos">
        <div class="grid-4">
          <div *ngFor="let lecture of allLectures">
            <app-video-item
              [latestLecturesList]="lecture"
            ></app-video-item>
          </div>
        </div>
      </div>
    </div>
  </div>
 

Thanks to everyone who will try to help.

Upvotes: 0

Views: 101

Answers (2)

Kanishk Anand
Kanishk Anand

Reputation: 1702

This is a problem with the how you're managing your allLectures variable. Either convert it to a map or object to store mapping of id to the result, or, concatenate to the existing allLectures so that it doesn't override the previous result with new API call data.

// In your component, declare these variables:

allLecturesMap = new Map();

ngOnInit(): void {
      this.getCategories();   
  }


  getCategories() {
    this.categoryListSubs = this.categoryService
      .getAllCategories(this.limit, this.offset)
      .subscribe((categories: any) => {
        this.allDataFromApi = categories;
        this.categoryList = categories.results;
        this.isLoaded = true;

          this.categoryList.forEach((el: any) => {
          this.categoryID = el.id;
          this.getLectures(this.categoryID);
        });
      });
  }

  getLectures(id: any): void {
    console.log(id);

    this.isLoaded = false;

    this.allLecturesOfCategorySubs = this.categoryService
      .getLecturesOfCategory(id, this.limit, this.offset, this.queryParams.sort)
      .subscribe((allLectures: AllLecture) => {
        // either use a map
        this.allLecturesMap.set(id, allLectures.results);
        // or concatenate 
        this.allLectures = [...(this.allLectures ?? []), ...allLectures.results]; // assuming its array
        console.log(this.allLectures);

        this.isLoaded = true;
      });
  }
}

If you choose to use Map or Object, you need to change your HTML code to iterate through it.

// considering Map
<div *ngFor="let item of allLecturesMap.entries()">
    <ng-container *ngFor"let lecture of item[1]"> 
     <app-video-item
         [latestLecturesList]="lecture"
     ></app-video-item>
    </ng-container>

</div>

Upvotes: 1

N.F.
N.F.

Reputation: 4182

You call getLectures per categoryID and you overwrite the result with this.allLectures = allLectures.results; in getLectures.

Try modifing it to this.allLectures.push(...allLectures.results);.

Upvotes: 1

Related Questions