Reputation: 744
I'm a beginner working on an app built with JHipster and using Angular 4.3. I'm using PrimeNG too.
I'm trying to use <p-toggleButton>
(here is the documentation), but my problem is that I update my value in my component.ts, but the html doesn't matter.
The use case is that with some conditions, users can't put the button into ON or OFF. So I've got to check the conditions and assign the toggle button according to the result.
My code looks like this :
HTML
<p-toggleButton [(ngModel)]="checked"
[value]="checked" // Tried [(ngValue)], (ngValue) too but doesn't work
(ngModelChange)="lockChanged()"
onLabel="ON" offLabel="OFF"
[style]="{'width':'150px'}">
</p-toggleButton>
TS
export class Component implements OnInit {
checked: boolean;
lockScreen: Lock;
lockItem: LockItem = [...];
constructor(
private lockService: LockService
) { }
ngOnInit() {
this.findLock();
}
lockChanged() {
this.lockService.find(this.lockItem).subscribe((res) => this.lockScreen = res);
if (this.checked) {
if (this.lockScreen.lockItem === undefined) {
let lock = new Lock();
this.lockService.create(lock).subscribe((res) => console.log(res));
this.checked = true;
} else {
// TODO error Message
}
} else {
if (this.lockScreen.lockItem !== undefined) {
this.checked = true;
console.log(this.checked); // is true
}
}
}
private findLock() {
this.lockService.find(this.lockItem).subscribe((res) => {
res.lockItem ? (this.checked = true, this.lockScreen = res) : (this.checked = false, this.lockScreen = res);
});
}
}
But even if I set the checked value to true or false, the html code doesn't matter. I've tried [(ngValue)], (ngValue) and [value] in the html... Does anyone have an idea ?
EDIT : Answers to comments + Solution
@Arash : I've tried (change), my function in my TS isn't called. I've no choice but using (ngModelChange)
@Skorunka František : If I put a disabled property, I can't use my toggle button because of the disabled status. So I can't use this.
@Shah : Yes, it doesn't have a property value, I've just tried solutions like when I use other components.
@Bharat Gupta : You partially solved my problem, thank you !
Here is the code that works :
HTML
<p-toggleButton [(ngModel)]="locked"
(onChange)="lockChanged()"
onLabel="ON"
offLabel="OFF"
[style]="{'width':'150px'}">
</p-toggleButton>
TS
this._ngZone.run(() => {
setTimeout(()=>{
this.locked = false;
},0);
});
Upvotes: 1
Views: 6331
Reputation: 2696
Quoting @Gunter from this answer:
Angular runs the code of your components within its zone where most async APIs (addEventListener, setTimeout, ...) are patched so the zone can notify Angular when such an async callback has happend. This is when Angular runs change detection.
If you initialized AssetService outside Angular or AssetService by other means executes code outside Angulars zone, then Angular doesn't get notified about happened async callbacks and doesn't run change detection.
So you might need to execute your changes within zone.run()
. First inject NgZone
into your component. And then lockChanged
needs to change like below:
lockChanged() {
this.lockService.find(this.lockItem).subscribe((res) => this.lockScreen = res);
if (this.checked) {
if (this.lockScreen.lockItem === undefined) {
let lock = new Lock();
this.lockService.create(lock).subscribe((res) => console.log(res));
this.zone.run(() => { this.checked = true });
} else {
// TODO error Message
}
} else {
if (this.lockScreen.lockItem !== undefined) {
this.zone.run(() => {
this.checked = true;
console.log(this.checked);
});
}
}
}
Similar changes would be needed to be done for findLock
function.
Upvotes: 2