ngOnChanges only works when it's not the same value

1.1k Views Asked by At

So basically I have a modal component with an input field that tells it which modal should be opened (coz I didn't want to make a component for each modal):

@Input() type!:string

 ngOnChanges(changes: SimpleChanges): void {
   this.type = changes["type"].currentValue;
   this.openModal();
}

that field is binded to one in the app component:

modalType = "auth";

HTML:

<app-modal [type] = modalType></app-modal>

In the beginning it's got the type "auth" (to login or register), but when I click on an icon I want to open a different modal, I do it like so:

 <h1 id="options-route"
    (click) ="modalType = 'settings'"
    >⚙</h1>

but this only works the first time, when modalType already has the value "settings" the event doesn't trigger even though the value has technically changed

I think the problem is that it's the same value because i tried putting a button that does the exact same thing but with the value "auth" again and with that it was clear that the settings button only worked when tha last modal opened was auth and viceversa

any ideas? I want to be able to open the settings modal more than once consecutively possibly keeping onChange because ngDoCheck gets called a whole lot of times and it slows down the app

2

There are 2 best solutions below

0
Rishabh On

You need to include the changeDetectorRef, in order to continue in this way. More about it https://angular.io/api/core/ChangeDetectorRef

Although, a better and a faster alternative is the use of a behavior Subject. All you have to do is create a service that makes use of a behavior subject to cycle through each and every value exposed and then retrieve that value in as many components as you want. To do that just check for data changes in the ngOnInit of target component.

You may modify this for implementation,

private headerData = new BehaviorSubject(new HeaderData());
headerDataCurrent = this.headerData.asObservable();
changeHeaderData(headerDataNext : HeaderData) {
this.headerData.next(headerDataNext)
console.log("subscription - changeUserData - "+headerDataNext);
}

Explanation: HeaderData is a class that includes the various values that can be shared with respective data types.

changeHeaderData({obj: value}), is used to update the subject with multiple values.

headerDataCurrent, an observable has to be subscribed to in the target component and data can be retrieved easily.

0
santocielo99 On

I mean i'm too l-a-z-y to use your slightly-not-so-much-tbh complicated answers so I just did this:

I added a counter that tops to 9 then gets resetted to 0 and I add it to the value

screwYouOnChangesImTheMasterAndYouShallDoMyBidding = 0;

 //gets called onClick
 openSettings(){
    if(this.screwYouOnChangesImTheMasterAndYouShallDoMyBidding === 9){
      this.screwYouOnChangesImTheMasterAndYouShallDoMyBidding = 0;
    }
    this.screwYouOnChangesImTheMasterAndYouShallDoMyBidding = this.screwYouOnChangesImTheMasterAndYouShallDoMyBidding + 1;
    this.modalType = "settings"+this.screwYouOnChangesImTheMasterAndYouShallDoMyBidding;
  }

then in the child component I just cut that last character out:

ngOnChanges(changes: SimpleChanges): void {
    let change = changes["type"].currentValue as string;
    change = change.substring(0, change.length - 1);
    this.type = change;
    this.openModal();
  }

works like a charm