dalezak
February 6, 2017, 11:13pm
1
I’m running into an issue using [(ngModel)] in a custom component with a RadioGroup that has dynamic RadioButton, getting the error:
Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
If I remove the [(ngModel)] binding, the RadioGroup renders fine but no RadioButtons are checked.
<ion-list radio-group [(ngModel)]="selection">
<ion-item *ngFor="let option of options">
<ion-label>{{option}}</ion-label>
<ion-radio [value]="option"></ion-radio>
</ion-item>
</ion-list>
I’m setting the options and selection in the ngOnInit method of the component.
Any idea why this is happening?
I’m not sure you’ve given us enough information, because the following works for me:
fruits: string[];
selection: string;
ngOnInit(): void {
this.fruits = ["apple", "banana", "cherimoya"];
this.selection = "banana";
}
<ion-list radio-group [(ngModel)]="selection">
<ion-item *ngFor="let fruit of fruits">
<ion-label>{{fruit}}</ion-label>
<ion-radio [value]="fruit"></ion-radio>
</ion-item>
</ion-list>
dalezak
February 6, 2017, 11:44pm
3
Hmm, still having the issue. The component does take a formGroup and formControlName as an input, something like:
<div [formGroup]="formGroup">
<ion-list radio-group [(ngModel)]="selection" [formControlName]="controlName">
<ion-item *ngFor="let option of options">
<ion-label>{{option}}</ion-label>
<ion-radio [value]="option" (ionSelect)="radioChanged($event)"></ion-radio>
</ion-item>
</ion-list>
</div>
Could the formGroup or formControlName be part of the problem?
Here is the full stacktrace from the error message:
[17:41:48] console.error: EXCEPTION: Error in ./ResponseAddPage class ResponseAddPage - inline template:34:78 caused
by: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
[17:41:48] console.error: ORIGINAL EXCEPTION: Expression has changed after it was checked. Previous value: 'true'.
Current value: 'false'.
[17:41:48] console.error: ORIGINAL STACKTRACE:
[17:41:48] console.error: BaseError@http://localhost:3000/build/main.js:13617:38
ExpressionChangedAfterItHasBeenCheckedError@http://localhost:3000/build/main.js:61791:20
checkBinding@http://localhost:3000/build/main.js:29926:115 checkHost detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
detectChangesInNestedViews@http://localhost:3000/build/main.js:117846:50 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
detectChangesInNestedViews@http://localhost:3000/build/main.js:117846:50 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
detectChangesInNestedViews@http://localhost:3000/build/main.js:117846:50 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
detectChangesInNestedViews@http://localhost:3000/build/main.js:117846:50 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
detectChangesInNestedViews@http://localhost:3000/build/main.js:117846:50 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48 detectChangesInternal
detectChanges@http://localhost:3000/build/main.js:117661:35
detectChanges@http://localhost:3000/build/main.js:117754:48
checkNoChanges@http://localhost:3000/build/main.js:62409:79 forEach@[native code]
tick@http://localhost:3000/build/main.js:41891:49 http://localhost:3000/build/main.js:41830:109
onInvoke@http://localhost:3000/build/main.js:44034:43 run@http://localhost:3000/build/polyfills.js:3:6487
next@http://localhost:3000/build/main.js:41830:84 http://localhost:3000/build/main.js:43234:56
__tryOrUnsub@http://localhost:3000/build/main.js:13398:20 next@http://localhost:3000/build/main.js:13347:34
_next@http://localhost:3000/build/main.js:13300:30 next@http://localhost:3000/build/main.js:13264:23
next@http://localhost:3000/build/main.js:21046:29 emit@http://localhost:3000/build/main.js:43226:80
checkStable@http://localhost:3000/build/main.js:44002:44
setHasMicrotask@http://localhost:3000/build/main.js:44073:25
onHasTask@http://localhost:3000/build/main.js:44046:46
_updateTaskCount@http://localhost:3000/build/polyfills.js:3:10535
invokeTask@http://localhost:3000/build/polyfills.js:3:9825
runTask@http://localhost:3000/build/polyfills.js:3:7093 i@http://localhost:3000/build/polyfills.js:3:3678
invoke@http://localhost:3000/build/polyfills.js:3:10877 dispatchEvent@[native code]
handleTapPolyfill@http://localhost:3000/build/main.js:78805:36
pointerEnd@http://localhost:3000/build/main.js:78715:35 [native code]
handleTouchEnd@http://localhost:3000/build/main.js:127568:41 [native code]
I still think you’re omitting the actual problem. Still working:
<div [formGroup]="form">
<ion-list radio-group [(ngModel)]="selection" formControlName="selection">
<ion-item *ngFor="let fruit of fruits">
<ion-label>{{fruit}}</ion-label>
<ion-radio [value]="fruit"></ion-radio>
</ion-item>
</ion-list>
</div>
ngOnInit(): void {
this.selection = "banana";
this.form = this._fb.group({
selection: ["banana"]
});
this.fruits = ["apple", "banana", "cherimoya"];
}
I don’t really understand why you have both an ngModel binding and a bound control: I would just do one or the other, but even with both it doesn’t break for me.
dalezak
February 7, 2017, 12:05am
5
Ah-ha! Trying to bind it in both the FormControl and ngModel must have been causing the issue, one was setting the checked and the other one changing it.
In your last example, try changing the following.
this.selection = "banana";
this.form = this._fb.group({
selection: [""]
});
Curious if you get the same error I was experiencing?
Negative, Ghost Rider.
Still works fine that way. If I make selection blank and set the control to “banana” instead, still no error, but now there is no checked selection at startup, so it looks like ngModel trumps the form control if there’s a disagreement.
Any chance your error is being caused by the presence of some event handler (like ionChange, for example)?
dalezak
February 7, 2017, 12:21am
7
Hmm, thats interesting, I thought maybe having conflicting values might be the issue.
Well the good news is, if I pass the value into the FormControl when I’m building the FormGroup, it properly binds to that value without needing to use ngModel in the view.
I was previously only using FormControl to include the Validators, and not passing in an initial value.
Thanks for pointing this out, I’ll need to review my FormGroup and FormControl components, but this definitely helps me out!