Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with async inputs in Components?

Tags:

angular

I am having an issue with ngOnChange. I have following component:

@Component({
    selector:'user-table',
    template: `...`,

})

export class UserTable implements OnChanges{
    @Input() users: User[];
    years:string[];
    constructor(private _usersCollection:UsersCollection){
    }

    ngOnChanges(){
     if (this.users.length)
       {this.years =this._usersCollection.createYearsArray(this.users)}
    }
}

However, if condition only gets checked once - when this.users is not yet fetched from the server, and hence its length is 0. How can I find solution to deal with this kind of async inputs?

The array is updated, as when I set the following logs:

    console.log('ON FIRST INIT' , this.programs);
    this.years = this._usersCollection.createYearsArray();
    console.log(this.years);
    setInterval(()=>{
        console.log('IN INTERVVAL' , this.programs);
    },1000);

The console output is:

ON FIRST INIT []
UsersTable.component.ts:21 []
UsersTable.component.ts:23 IN INTERVVAL [Object, Object, Object, Object]
like image 941
uksz Avatar asked Mar 14 '16 15:03

uksz


People also ask

Can we use async await in angular?

Using Async/Await in AngularOne of the best improvements in JavaScript is the Async/Await feature introduced in the ECMAScript 7. Basically, Async/Await works on top of Promise and allows you to write async code in a synchronous manner. It simplifies the code and makes the flow and logic more understandable.

What is async pipe in angular?

Angular's async pipe is a tool to resolve the value of a subscribable in the template. A subscribable can be an Observable , an EventEmitter , or a Promise . The pipe listens for promises to resolve and observables and event emitters to emit values. Let's take a look at how we can profit from using the async pipe.

How does angular handle async data?

Solution 1: Use *ngIf Solution one is the easiest. Use *ngIf in blogger component to delay the initialization of posts components. We will bind the post component only if the posts variable has a value. Then, we are safe to run our grouping logic in posts component ngOnInit .


2 Answers

If you don't need to execute any logic when your input property changes (e.g., you only use the property in template bindings), you don't need to do anything. Angular will automatically propagate new values down from the parent to the input property.

If you want to execute some component logic when the input property changes, use ngOnChanges(), which is called whenever any component input property changes.

Since Angular uses === to detect changes (well, there's some special handling for NaN too), this means that

  • for reference types (Array, Object, Date, etc.), the reference (i.e., the array, object, etc. reference) must change. E.g., myArray = someNewArray;
    If only an item in the array changes, ngOnChanges() is not called. E.g., for a change such as myArray[0].name = newName;, ngOnChanges() is not called.
  • for primitive types (number, boolean, string), this simply means that the value must change. E.g, myNumber = 5; or myNumber = newNumber;

Another option is to implement your own change detection logic using ngDoCheck(). See this answer for an example. That lifecycle hook is called "every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check" -- from lifecyle hooks.md

like image 98
Mark Rajcok Avatar answered Oct 11 '22 12:10

Mark Rajcok


ngOnChanges() gets called when users are updated. You just need to make sure a new array is assigned users in the parent component instead of filling an existing array. Otherwise Angulars change detection won't recognize the change.

like image 35
Günter Zöchbauer Avatar answered Oct 11 '22 13:10

Günter Zöchbauer