0

I am getting list of "incident_ids" from a HTTP get call as shown in the ts file and populating in the HTML in the mat-nav-list. Problem is mat-nav-list inside cdk-virtual-scroll-viewport not getting updated with the HTTP data but when I remove cdk-virtual-scroll-viewport the mat-nav-list is showing the data.

Here's my HTML file

<mat-card class="home-card">
<table class="home-table">
    <tr> 
        <th class="header-incident"> INCIDENTS </th>
        <th class="header-incident-details"> 
            <mat-card class="incident-details-card"> INCIDENT DETAILS </mat-card>
        </th>
    </tr>
    <tr>
        <td>
            <input placeholder="Search Ex: INC12345678" class="incident-search" (keyup)="refresh_data()">
        </td>
    </tr>
    <tr>
        <td class="incident-list">
            <cdk-virtual-scroll-viewport [itemSize]="1" >
                <mat-nav-list>
                    <a mat-list-item href="#" *cdkVirtualFor="let link of incident_ids" > {{ link }} </a>
                </mat-nav-list>
            </cdk-virtual-scroll-viewport>
        </td>
    </tr>
</table>

Here's my ts file

    import { Component, OnInit } from '@angular/core';
import { IncidentService } from '../incident.service';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

export class HomeComponent implements OnInit{

  incident_ids: any = [] 

  constructor(private incidentService: IncidentService) { }

  ngOnInit(): void {
    this.incidentService.get_incident_numbers()
      .subscribe(data => {
        for (let val of data.d.results){
          this.incident_ids.push(val.INCIDENT_NUMBER)
        }
      })
  }

  refresh_data() {
    console.log(this.incident_ids[0])
  }

}

Here's my API call inside service file

    get_incident_numbers(): Observable<any>{
    const url = this.baseUrl + "?$format=json&$select=INCIDENT_NUMBER"
    return this.http.get(url, this.httpOptions)
  }

Can anyone please point out what I am missing?

kethan bravo
  • 93
  • 2
  • 6
  • 1
    I'm new to Angular, but this is likely due to change detection not being able to see that you've updated the data. Change `this.incident_ids.push(val.INCIDENT_NUMBER)` to `this.incident_ids = [...this.incident_ids, val.INCIDENT_NUMBER]`. Or get rid of the loop and do `this.incident_ids = [...this.incident_ids, ...data.d.results.map(val => val.INCIDENT_NUMBER)]`, which is a little more efficient (maybe take that `map` into its own variable for cleanliness though). – Carcigenicate Jan 09 '22 at 15:22
  • Thank you @Carcigenicate, It worked, But I still did not find why the problem has occurred in the first place – kethan bravo Jan 09 '22 at 17:40
  • The problem was, that in the first approach the `this.incident_ids` instance reference did not change, this is why Angular change detection had no clue about the data structure change. If `[...this.incident_ids, val.INCIDENT_NUMBER]` is used, the `this.incident_ids` gets a reference to a newly created instance, which is different than the original, this is why the Angular change detection notices the change and does the necessary update. – Milan Tenk Jan 09 '22 at 18:27
  • @kethanbravo Angular can't detect the mutation of objects, only the reassignment of references to objects (from my understanding). My solution creates a new list and reassigns to it, which Angular can detect. – Carcigenicate Jan 09 '22 at 18:46
  • Got it, change detection happens when there's a pure change. Thanks – kethan bravo Jan 09 '22 at 19:37

0 Answers0