DA.
DA.

Reputation: 40663

angular changes.subscribe not firing

I want to update the UI of a component after it's fully rendered. Because it's rendering elements in a for, my understanding is that I need to use a subscription to check for the elements to first be created before I interact with the UI.

Based on examples I've read, this is what I came up with. However, nothing happens in that my console.log statement inside my subscription never fires. No errors. It's as if my subscription doesn't see any changes. Is there anything obviously missing from my logic here?

template markup:

<ng-container *ngFor="let item of items; let i = index;">
    <input *ngIf="..." #inputItem>

Angular (5):

@ViewChildren('inputItem', {read: ViewContainerRef }) inputItems: QueryList<ViewContainerRef>;

ngAfterViewInit(): any {
    this.inputItems.changes.subscribe(() => {
        console.log('items created');
    });
}

Upvotes: 2

Views: 4024

Answers (1)

DeborahK
DeborahK

Reputation: 60518

It worked fine for me with a few minor changes. This is what I ended up with:

Template

<tr *ngFor='let product of filteredProducts' >
  <input *ngIf='product.imageUrl' #inputItem type='text'>

Component

import { Component, OnInit, ViewChildren, 
         QueryList, AfterViewInit, ElementRef } from '@angular/core';

@ViewChildren('inputItem') inputItems: QueryList<ElementRef>

  ngAfterViewInit(): void {
    this.inputItems.changes.subscribe(value => {
      console.log(value);
      this.inputItems.map((item => item.nativeElement.style.backgroundColor = 'red') )
    }
    );
  }

UPDATE 8/8/19 RE: Unsubscribing:

Technically, you should not have to unsubscribe from any Observables defined on an element as they will be destroyed when the form is destroyed.

However, developers in general have been moving to a more explicit approach and been using the rule that if you subscribe you should always unsubscribe.

In the apps I work on now, I use the async pipe exclusively (as shown here: https://github.com/DeborahK/Angular-RxJS) and therefore have no subscribes (and no unsubscribes).

If you did want to unsubscribe from the above, you would first need to put the subscription into a class variable:

this.sub = this.inputItems.changes.subscribe(...);

Then in the destroy:

this.sub.unsubscribe();

Upvotes: 2

Related Questions