2

I want a method get called automatically when template get completely loaded. I have tried lifecycle hooks of ionic as well as angular and I have also tried to call method from template. html

My HTML file contains the following:

<h1>{{ myMethod() }}</h1>

But this is calling the myMethod function many times.

coder
  • 8,346
  • 16
  • 39
  • 53
Tony Stark
  • 265
  • 2
  • 16
  • What does `myMethod` do, and why is it not acceptable for this function to be called multiple times? – David Walschots May 20 '18 at 14:17
  • I want to load map on device when side menu button is clicked. That's why it is unacceptable to be called multiple times. – Tony Stark May 20 '18 at 14:42
  • So `myMethod` loads the map? Shouldn't this then be called by the button's click event? You should assume bindings like this in the view _will_ be called multiple times. – David Walschots May 20 '18 at 14:43
  • did you try `ngAfterViewChecked`? that's the last lifecycle hook which runs after components & all its children are fully rendered with DOM changes applied. – dee zg May 20 '18 at 15:04
  • @David On clicking side menu button. It reset root page again. And load new page. Hence click event is not of much use. – Tony Stark May 20 '18 at 15:05
  • @dee I have tried it too. Problem with **ngAfterViewChecked** it is called many times. – Tony Stark May 20 '18 at 15:08
  • sure but, what prevents you to put a property flag on component `ranAlready:boolean = false`, set it to `true` on first `ngAfterViewChecked` run and call the function only if that boolean is false? – dee zg May 20 '18 at 15:10
  • @deezg template is does not load on second or third call of **ngAfterViewChecked**. – Tony Stark May 20 '18 at 15:17
  • i am not actually sure what exactly do you mean by 'how would i know that template is loaded'? – dee zg May 20 '18 at 15:20
  • I want to call a method when template get displayed on screen. – Tony Stark May 20 '18 at 15:21
  • then use what i proposed. check also: https://stackoverflow.com/questions/41391939/angular2-ngafterviewchecked-is-called-many-times-how-to-call-a-method-just-o – dee zg May 20 '18 at 15:22
  • I have tried all the **angular and ionic lifecycle hooks.** – Tony Stark May 20 '18 at 15:24
  • that doesn't help. What is the problem with `ngAfterViewChecked` in particular? does it run too early for you or it doesn't run too early but it runs many times? – dee zg May 20 '18 at 15:26
  • there are two problem with **ngAfterViewChecked**. First it runs many times and second it executes from **"before loading template"** till **"template get loaded"** but I am not able to know after which **call** template get loaded. – Tony Stark May 20 '18 at 15:32
  • Don't get me wrong, but i am pretty sure something is missing in this question description. People are counting precise scrolling positions with `ngAfterViewChecked': https://stackoverflow.com/questions/31171084/how-to-call-function-after-dom-renders-in-angular2 Its hard for me to believe you wouldn't be able to do what you're saying. – dee zg May 20 '18 at 15:38
  • @deezg no brother I am not getting you wrong. I know you are doing your best to help me in my problem. I really want to thank you for this. You can see [here](https://drive.google.com/drive/folders/1y-xLc_4-p9aq8jGqpZCB0tjSg0WvwKSJ) I have uploaded screenshot of each call. Main problem with this is that I don't know which before which call my template gets loaded on display. – Tony Stark May 20 '18 at 15:53
  • does that particular component you're waiting to load have children components? – dee zg May 20 '18 at 16:02
  • Yes. It have 1 div child component and nested components. – Tony Stark May 20 '18 at 16:09
  • and, 2 questions then: 1) are you're waiting for all of them to load and be shown on screen before you fire your function or you need some particular one to be loaded? 2) does any of your child/sibling components have any kind of async calls before they load? – dee zg May 20 '18 at 16:12
  • 1) I want to wait for a particular component to be shown on screen before I can fire my function. 2)Yes I have async calls before they load. – Tony Stark May 20 '18 at 16:16
  • have you tried isolating that particular 'thing' into a single component (that will have no children) and use its `ngOnViewInit/ngOnViewChecked`? if needed, you could emit `@Output()` event from it to parent if parent is the one that should load the map. btw, this also might be useful: https://stackoverflow.com/questions/40938422/angular-2-calling-jquery-after-rendering-elements-after-consuming-api – dee zg May 20 '18 at 16:19
  • I will try this. Thanks :) – Tony Stark May 20 '18 at 16:22

2 Answers2

1

Because you need to call myMethod() only one time, it is better to use ionViewDidLoad. Because this event fired only when a view is stored in memory. This event is NOT fired on entering a view that is already cached. you could find out more information from here.

So if you need to call the method (myMethod()) even after this event is fired it is better to use timeout inside this event to call your method. Give desire timeout that match with your scenario.

Sample code:

ionViewDidLoad() {
  setTimeout(() => {
    myMethod();
  }, 300);
}

Hope this will help to solve your problem.

David Walschots
  • 12,279
  • 5
  • 36
  • 59
coder
  • 8,346
  • 16
  • 39
  • 53
  • Doesn't it make unnecessary delay in the app. – Tony Stark May 20 '18 at 15:02
  • but this is the only place match with your problem. try to adjust that delay according to your scenario in effective and efficient way. this is not unnecessary delay. because it is necessary to solve your problem. Also this delay effect to your app only one time. – coder May 20 '18 at 15:06
  • I think of this earlier but I don't want to use it. Now I realised that there is no other way and have to use timeout only. Thanks – Tony Stark May 20 '18 at 15:11
  • np :) if you find out another way to achieve this don't forget to update here.. ;) – coder May 20 '18 at 15:20
  • sure. I will :) – Tony Stark May 20 '18 at 15:22
  • what happens if he changes the structure/number/complexity of sibling components and their children? should he readjust the timeout? – dee zg May 20 '18 at 15:24
  • when it's fired the `ionViewDidLoad`, the other components and their children in that view has been already loaded. that part would be handled by the ionic. timeout effect only after that part – coder May 20 '18 at 15:38
  • i am not that familiar with ionic to know all the details but whenever i see a need to 'adjust timeouts' i am very cautious. my first question in approaching this would be: why 300ms? or, if you would have written whatever number of ms - i'd still ask 'why that particular number'? – dee zg May 20 '18 at 16:10
  • i just put that number only as a e.g in sample code. If you want you could reduce until match with what ever scenario you deal with.. :) – coder May 20 '18 at 16:22
0

You should go for ngAfterViewInit life cycle hook. ngAfterViewInit() is called after the view is initially rendered.

export class YourComponent implements AfterViewInit {    
  constructor() {    
  }

  ngAfterViewInit() {
    myMethod();
  }
}
David Walschots
  • 12,279
  • 5
  • 36
  • 59
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396