Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Virtual Scroll Not Detecting Changes to Add Items for Reactive FormArray

I am working with the new control in Angular 7 and cannot seem to get it to recognize that I've added a new item to the array that is being displayed.

Here is my html:

<cdk-virtual-scroll-viewport class="list-container lg" [itemSize]="52.5">
    <div *cdkVirtualFor="let state of statesObservable | async;" class="list-group-item">
        <div class="state">{{state.name}}</div>
        <div class="capital">{{state.capital}}</div>
    </div>
</cdk-virtual-scroll-viewport>

and here is the setup for the component:

import { Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Component({
  selector: 'app-virtual-scroll',
  templateUrl: './virtual-scroll.component.html',
  styleUrls: ['./virtual-scroll.component.css']
})
export class VirtualScrollComponent {

  states = [
    { name: 'Alabama', capital: 'Montgomery' },
    { name: 'Alaska', capital: 'Juneau' },
  ];
  statesObservable = new BehaviorSubject(this.states);

  sortBy(prop: 'name' | 'capital') {

    // this works -- creates a new array
    this.statesObservable.next(this.states.map(s => ({ ...s })).sort((a, b) => {
      const aProp = a[prop], bProp = b[prop];
      if (aProp < bProp) {
        return -1;
      } else if (aProp > bProp) {
        return 1;
      }
      return 0;
    }));
  }

  addItem() {
    // this does not work
    this.states.push({ name: 'Wyoming', capital: 'Cheyenne' });
    this.statesObservable.next(this.states);
  }

}

I've created a stackblitz of the issue (based on an existing stackblitz that I found):

https://stackblitz.com/edit/angular-material-wlrjys

The very weird thing is that if you recreate the array by using a map function, it works and and the newly added items appear.

I've traced the issue into the guts of core.js and it looks as if it's not seeing the change to the array when I call .next() on the BehaviorSubject.

Any help is appreciated --

UPDATE

Of course, 10 minutes after I post this (after two days of searching) I find (half) the answer I'm searching for. It looks like change detection is not picking this up because I'm not changing the variable itself, just adding to it. Which I understand. The question is, how do I get a new variable for an existing FormArray -- do I have to recreate the entire thing? Seems like overkill.

like image 968
John Azzolina Avatar asked Nov 06 '22 23:11

John Azzolina


1 Answers

clone it

  this.FormArray = [...this.FormArray];
like image 180
Omar Salem Avatar answered Nov 11 '22 11:11

Omar Salem