Function passes only once in ngOnInit

ngonchanges
angular lifecycle hooks
pass async data to child component - angular 8
ngafterviewinit
ngoninit example
angular pass async data to child component
pass observable to child component
angular pass observable as input

I developed a service that allows me to activate a button and see its status in the different components. When I click start / pause, the button changes image.

In StackBlitz, the code works perfectly, but when I implement it in my project, the function only passes once in ngOnInit and no longer loads, no longer changing the image of the buttons between the components.

Is there a way to implement this but without using ngOnInit?

I used setinterval and the button changes the image, but it doesn't seem the best solution.

Can anyone help me?

Stackblitz

Problem --- component about

currentState: string;
ngOnInit() {
    this.currentState = this.servicesService.getCurrentState();
}

html

<div class="container" style="margin-top: 10%">
    <div class="btn-group" dropdown>
        <button id="button-basic" dropdownToggle type="button" class="btn ">
            <img style="width: 35px;" *ngIf="currentState=='pause'" src="https://img.icons8.com/carbon-copy/100/000000/play-button-circled.png">
            <img style="width: 35px;" *ngIf="currentState=='start'" src="https://img.icons8.com/cute-clipart/64/000000/stop-squared.png">
        </button>
        <ul id="dropdown-basic" *dropdownMenu class="dropdown-menu" role="menu" aria-labelledby="button-basic">
            <li role="menuitem">
              <a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active" (click)="startTimer()">Start</a>
            </li>
            <li role="menuitem">
              <a class="dropdown-item" *ngIf="currentState=='start'" routerLinkActive="active" (click)="pauseTimer()">Stop</a>
            </li>
        </ul>
        <div>
            <span>{{servicesService.fetchDisplay()}}</span>
        </div>
    </div>
</div>

Component

 startTimer() {
    this.servicesService.startTimer();
    this.currentState = this.servicesService.getCurrentState();
 }

 pauseTimer() {
    this.servicesService.pauseTimer();
    this.currentState = this.servicesService.getCurrentState();
 }

you can define your service as public

constructor(public servicesService: ServicesService) { }

and in your html

*ngIf="servicesService.getCurrentState()=='pause'" 

Ionic router. OnInit working only once � Issue #17853 � ionic-team , Because of this I cannot unsubscribe an observable that I passed to the It can execute a certain function(call ngOnInit again). Why ngOnInit() works only once when I come back to home page the data not displaying. :(. ngOnInit is only called, when the angular component gets initialised, which is not the case for ionic routing. the previous pages are cached and only disconnected from the change detection. The ionic component lifecycle hooks and the angular router events/observables should fulfill your needs. It is like ionic navigation is working.

component

constructor(private servicesService: ServicesService) {}

public get isPlaying() {
   return this.servicesService.getCurrentState() === 'play';
}

public get isPaused() {
   return this.servicesService.getCurrentState() === 'pause'
}

HTML

*ngIf="isPlaying" 

or

*ngIf="isPaused" 

3 Ways to Pass Async Data to Angular 2+ Child Components , 3 Ways to Pass Async Data to Angular 2+ Child Components The groupByCategory function is our core logic to group the posts by category. Since the grouping logic runs in ngOnInit , that means it will run only once. ngOnInit fires once upon initialization of a component’s input-bound (@Input) properties. The next example will look similar to the last one. The hook does not fire as ChildComponent receives the input data. Rather, it fires right after the data renders to the ChildComponent template.

The ngOnInit is a licefycle hooks and always runs exactly once. If you want to execute something everytime a value changes, you need a different hook. In your case probably ngOnChanges.

This one gets called everytime a component binding value changes.

For more information on the different hooks I recommend: https://angular.io/guide/lifecycle-hooks

NgOnInit & Constructor Differences In Angular With Examples , ngOnInit and constructor methods in Angular might be confusing to you,if you are new to Angular. Our ngOnInit() method is just a method being added to the prototype of the class. Here I am using @Input Decorator to pass value from parent component CheckboxlistComponent It is called only once. Note that ngOnChanges hook is fired before ngOnInit. Which means all the input properties are available to use when the ngOnInit is hook is called. This hook is fired only once. This hook is fired before any of the child directive properties are initialized.

Passing Data to a Nested Component with @Input, ngOnInit() is one of the lifecycle hooks in Angular, called after the constructor() and ngOnChanges() method. You can learn more about angular� In other words, The ngOnInit() lifecycle hook Initialize the component after Angular first displays the data-bound properties and sets the component’s input properties It is a guarantee that our bindings are readily available. It is called only once. When to use constructor & when to use ngOnInit in Angular

48 answers on StackOverflow to the most popular Angular questions , How to pass url arguments (query string) to a HTTP request on Angular; How do you then to use the method of OnInit we have to implement in the class like this. It is invoked only once when the directive is instantiated. To conclude, the ngOnInit is purely there to give us a signal that Angular has finished initialising the component - and we’re ready to roll. This initialisation phase includes the first pass at Change Detection, which means any @Input() properties are available inside ngOnInit , however are undefined inside the constructor , by design.

Exploring Angular Lifecycle Hooks – OnInit, Called once, after the first ngOnChanges().” Why can't I just put my initialization logic in the class constructor ? OnInit is an Angular lifecycle method, that can be hooked into components and directives in This means we can access anything passed down into the component inside the ngOnInit hook. ngOnInit () link. A callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated. There are no parameters.

Comments
  • ngOnInit on component lifecycle runs only once. If you wan't to run something more than once, than you need to use setInterval etc. If you need to run it once, but after view is inited, then you can try ngAfterViewInit
  • Hello ! you actually need to use a state in different component, I'm not going to respond to your question but I wanted you to have a look to blog.angular-university.io/angular-2-redux-ngrx-rxjs . NGRX can be a good alternative if you planned to use differents states in multiples components :) Just a blog that you should read if you don't know NGRX, If you still want to use this service patern I will suggest you to get your current state in the *ngIf like this : *ngIf="this.servicesService.getCurrentState() === 'pause'"
  • Afaik the service does not have to be public though to consume it in the same component.
  • @lama Please can you explain why? I would like to know why you think so.
  • Sorry, although it works with the JIT compiler, it is not with AOT. @AshotAleqsanyan is right, my mistake.
  • @lama If I correctly understand what you say. I have used this many times and compile project with --AOT, everything works as expected.
  • If you inject a "private" service, it does not work with AOT, but as you suggested "public" does. "private" would work as long as he would use the JIT compiler. That is what I mean. Here is a discussion: stackoverflow.com/a/46596546/4827723
  • Thanks for trying help me, best regards !