admin管理员组文章数量:1401298
I was going through an Angular code in one of my existing projects and found below snippet.
We are using Angular material datatable
to render the view on the page
export class Component implements OnInit,AfterViewInit{
private dataSource: MatTableDataSource<Product> = null;
@ViewChild(MatPaginator) paginator: MatPaginator;
columnsToDisplay = ['productId','productname'];
constructor(private _service : DataService) { }
ngOnInit() {
this._service.getProducts().subscribe(
((data : Product[]) => this.dataSource = new MatTableDataSource(data)),
() => console.log('THIS IS ERROR')
);
setTimeout(() => this.dataSource.paginator = this.paginator);
//this.dataSource.paginator = this.paginator;
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
}
My question is :
1) Since this.service.getData()
returns an Observable
and subscribe
will be called asynchronously whenever the HttpResponse
is available ,
does operation inside setTimeout
function will be called ONLY AFTER the subscribe
method is called ?
2) I have seen that ngAfterViewInit
method also contains exactly the same code as in setTimeout
method in ngOnInit
method
3) But when this method is called (ngAfterViewInit)
, this.products
is still NULL indicating that subscribe is not yet called '
4) Is that the reason setTimeout
is called inside ngOnInit
method ?
5)If this is the case , what is the use of ngAfterViewInit
method ?
I was going through an Angular code in one of my existing projects and found below snippet.
We are using Angular material datatable
to render the view on the page
export class Component implements OnInit,AfterViewInit{
private dataSource: MatTableDataSource<Product> = null;
@ViewChild(MatPaginator) paginator: MatPaginator;
columnsToDisplay = ['productId','productname'];
constructor(private _service : DataService) { }
ngOnInit() {
this._service.getProducts().subscribe(
((data : Product[]) => this.dataSource = new MatTableDataSource(data)),
() => console.log('THIS IS ERROR')
);
setTimeout(() => this.dataSource.paginator = this.paginator);
//this.dataSource.paginator = this.paginator;
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
}
My question is :
1) Since this.service.getData()
returns an Observable
and subscribe
will be called asynchronously whenever the HttpResponse
is available ,
does operation inside setTimeout
function will be called ONLY AFTER the subscribe
method is called ?
2) I have seen that ngAfterViewInit
method also contains exactly the same code as in setTimeout
method in ngOnInit
method
3) But when this method is called (ngAfterViewInit)
, this.products
is still NULL indicating that subscribe is not yet called '
4) Is that the reason setTimeout
is called inside ngOnInit
method ?
5)If this is the case , what is the use of ngAfterViewInit
method ?
-
From what I can tell there's no reason to have either of the
setTimeout
s. It seems like it might have been done to set a default value for products, but that doesn't need to be done asynchronously. – Explosion Pills Commented Sep 24, 2018 at 12:16 - I have added few more details in my question. Please check – Atul Commented Sep 24, 2018 at 12:41
3 Answers
Reset to default 21) It depends. the subscription execute the code only when the action is done. So, when the this.service.getData()
has finished its job. The setTimeout do the job after a delay. If the subscription need less time than the setTimeout, it will be executed first.
2) Maybe you were trying to notice when the function is executed?
3) the AfterViewInit is fired multiple times. You can check like this if(!!something)
and then execute some code.
4) you should ALWAYS avoid to use settimeout (just use it for debug purposes).
EDIT:
ngOnInit() {
this._service.getProducts().subscribe(
((data : Product[]) => this.dataSource = new MatTableDataSource(data)),
() => console.log('THIS IS ERROR')
);
setTimeout(() => this.dataSource.paginator = this.paginator);
//this.dataSource.paginator = this.paginator;
} `
Let's simply this code a bit:
ngOnInit() {
this.service.doStuff()
.subscribe(result => {
this.functionA();
},
err => {
//Do other stuff in case of an error
});
this.functionB();
}
functionA(){
console.log("Hello,");
}
functionB(){
console.log("world!");
}
The output of this code will be:
world!Hello,
But why?
That's because of the observable
pattern.
You can imagine that as you walking with two people: one that know english, one that doesn't. So even if you say "How are you?" first to the guy who doesn't know english, he will need time to understand what did you say and answer you. At the same time, the other guy (that know english very well) answer you instantly.
The example of functionA
and functionB
is the same. FunctionA is executed only when the subscription has catch something. That's why it isn't fired first. You can see that putting a debug point here:
ngOnInit() {
this.service.doStuff()
.subscribe(result => {
---> this.functionA();
},
err => {
//Do other stuff in case of an error
});
---> this.functionB();
}
hope to have explained well this.
Now let's move on, let's use the timeout:
ngOnInit() {
this.service.doStuff()
.subscribe(result => {
this.functionA();
},
err => {
//Do other stuff in case of an error
});
settimeout(() => {
this.functionB();
}, 500);
}
Which function will be executed first?
Spoiler: You can't know that.
If you are wondering why, it's easy: You know exactly that the functionB will be called after 500ms, but you can't know how much time will use the subscription to be ready. So if you are lucky, and your subscription usually need about 500ms to plete, you can try to reload the page several time, sometimes you will see Hello, world!
, sometimes you will see world!Hello,
.
To answer in a better way at your questions: I don't really know why did you put the code like this, literally no idea.
The ngAfterViewInit is a life-cycle
called after the ngOnInit, and execute the logic after Angular has fully initialized a ponent's view.
I will try to simplify the description:
setTimeout puts the inside function in the end of the javascript queue so while javascript process is running it will pop up from the stack and call the operation. anything in the queue will get called only if the stack is empty. so
setTimeout
tells javascript to hold the this code till you finish your work.subscribe and observable: observable is async data structure so once you subscribe to it you can never now how much time it will take to call the subscribe method. in other words, subscribe will get called only if as example http response returns.
Back to your question: you can not know when your setTimeout code get called but theoretically it will get called before subscribe (javascript engine faster than http response).
If you need to initialize some data table structure only after you get the data from the http request you should put it inside the subscribe
method and no need for setTimeout.
ngAfterViewInit
is used by angular to tell the developer that in this stage your view
is ready and you can as an example use elementRef.
ngOnInit
is used by angular to tell the developer that all the inputs and directives ...etc.
1. no , setTimeout will be called only once and before subscribe as its outside of its context.
2. because of Asynchronous update , if we update properties asynchronously the values will not be updated when the verification loop is running and we get no error.
3. the ViewChild is available only after ngAfterViewInit. it populates the children when creating a view and so they are available earlier.
4. ngOnInit lifecycle hook is triggered before the DOM update operation and will give no error. ngOnInit lifecycle hook is triggered after the bindings have been processed . ngAfterViewInit is invoked when the view is initially rendered i.e. it's called after a ponent's view, and its children's views, are created.
5. ngAfterViewInit() should be called after a ponent's view, and its children's views, are created, most importantly children's ngAfterViewInit()s are called before the parent's ngAfterViewInit().
本文标签:
版权声明:本文标题:javascript - SetTimeOut function inside ngOnInit of Angular component while using Angular Material DataTable - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744271340a2598197.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论