juanp_1982
juanp_1982

Reputation: 1007

Angular: How to update view when Array changes?

I have been reading post and googling an answer for this question without any success

I looked into these two links and nothing

Angular doesn't update view when array was changed

Updating HTML view when Angular array changed

I have two components (siblings) one component add Items and the other lists all items added. The idea is very simple, whenever someone adds an item I want to update the list in order to get that new item.

export class ListItem implements OnInit {
  list: SomeObject[] = [];

  constructor(private myService: SomeService) {}

  ngOnInit() {
    this.getItems();
  }

  getItems(): void {
    this.myService.getDomesticatedPokemons()
      .subscribe((newItems) => {
        this.list = newItems; // I can see that this line works as expected but the view doesn't get updated though
      });
  }
}

export class AddItem implements OnInit {
  constructor(private myService: SomeService, private list: ListItem) {}

  ngOnInit() {

  }

  saveItem(aForm: NgForm): void {
    // ...
    // ...
    // ...
    // ...

    this.myService.addItem({}).subscribe((result) => {
      if (result.ok === 1) {
        this.list.getItems();
      } else {
        console.error('Error: ...');
      }
    });


  }
}

UPDATE:

this is the view:

<!-- This is the list template -->
<div id="list">
    <div *ngFor="let item of list" class="item">
       ...
       ...
       ...
    </div>
</div>

for the add component there is a form and saveItem() is executed on submit

UPDATE 2: I created a stackblitz this example is working even though I couldn't (or at least I didn't know how) reproduce my service getting data from server. I commented out "more realistic" code the main component is list.

Upvotes: 2

Views: 9792

Answers (1)

Shrinivas
Shrinivas

Reputation: 853

I have tried to solve your problem statement:

component to insert into the list

view:

<h3>create list</h3>
Foo:
<input type="text" class="form-field" [(ngModel)]="newItem.foo"><br/>
Bar:
<input type="text" class="form-field" [(ngModel)]="newItem.bar"><br/>
<button class="btn" (click)="addItem()">Add</button>
<button class="btn" (click)="resetForm()">Reset</button>
<hr>

controller:

export class CreateListComponent  {
  public newItem:Object;

  constructor(private listService: ListService) {
    this.newItem = this.setInital();
  }

  private setInital(){
    return {
      foo: null,
      bar: null
    };
  }
  public addItem(){
    this.listService.addItem(this.newItem);
    this.resetForm();
  }

  public resetForm(){
    this.newItem = this.setInital();
  }
}

component to display the list

view:

<h3>display list</h3>

<div *ngFor="let item of list">
  {{item.foo}} - {{item.bar}}
</div>

controller:

export class DisplayListComponent implements OnInit, OnDestroy {
  public list = [];
  private subscription: Subscription;

  constructor(private listService: ListService) { }

  ngOnInit() {
    this.getList();
  }

  private getList() {
    this.subscription = this.listService.getFooBarList().subscribe(data => {
        this.list.push(data);
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Since both the components are at same hierarchy, I have used service and observable to pass data from create component to display component

service:

export class ListService {
  private listSubject = new Subject();

  constructor() {}

  public addItem(item: any) {
    this.listSubject.next(item);
  }

  public getFooBarList() {
    return this.listSubject.asObservable();
  }
}

I hope this helps you. For a working sample please refer this stackblitz.

Upvotes: 3

Related Questions