You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think @Rakeshkohli is right and it should be [checked]="showHeroes for consistency purposes. I'm actually surprised [checked]="toggleHeroes also works - could someone explain this behavior?
Agreed, @dariobraun! I couldn't figure out how it was working both ways either. I've raised a flag on this one for engineering help, so we should get clarification soon.
@dariobraun@kapunahelewong
Second, I am getting unchecked checkbox when I remove function - toggleHeroes() from ts file. It means this function giving true value to checkbox that's why it is checked on page load but as we know function is called on click. This is very surprised thing.
Thanks for the bump, @dariobraun. Let me see if I can get some input. I think the right thing to do is change it. But why @Rakeshkohli gets the unchecked checkbox when removing the function, I'm not sure. I'll be back with some more info.
Here is why it (kind of) works with [checked]="toggleHeroes":
What [checked]="<expression>" does is evaluate <expression> and set the .checked property of the input to the resulting value. Of course, the correct expression would be showHeroes, which is a boolean property on the component instance.
By using toggleHeores (which is a method on the component instance), Angular will set input.checked to componentInstance.toggleHeroes. Since methods are functions and functions are truthy in JavaScript, the browser will consequently set input.checked to true. This will make the checkbox checked on load, which also happens to coniside with showHeroes being initialized to true. (I.e. if showHeroes was set to false in the component instance, the checkbox would still be checked - which would not be our intention.)
Now, upon clicking on the checkbox, the default browser behavior will kick in and toggle the checkbox's checked property. At the same time, Angular will evaluate the (click) handler expression (toggleHeroes()) and correctly toggle showHeores, which is turn determines whether the heroes section will be shown or hidden (due to *ngIf="showHeroes").
Finally, Angular will again evaluate the [checked] expression, which will always evaluate to the toggleHeroes method (note it evaluates to the method itself, it does not call the method). Since the value is the always the same as the previous value (the toggleHeroes method), Angular will skip updating the .checked property, leaving it to value currently set by the browser built-in click behavior.
(Note that if Angular didn't have the optimization of skipping updating the property if the expression value hasn't changed since the last check, then Angular would always update input.checked to a truthy value and thus the checkbox would always be checked. So the example only works, because of this optimization, which basically makes [checked]="toggleHeroes" only take effect on page load.)
I hope that (kind of) makes sense. Let me know if anything isn't clear.
And just to be clear, yes, the example is wrong and it should be showHeroes, as already mentioned 😁
Activity
kapunahelewong commentedon Jul 24, 2019
Thank you, @Rakeshkohli. I'll get confirmation, but your question seems relevant.
Adding link for reference. All the other checkboxes use
[checked]="show___".https://stackblitz.com/angular/gdearxmxrem
dariobraun commentedon Aug 1, 2019
I think @Rakeshkohli is right and it should be
[checked]="showHeroesfor consistency purposes. I'm actually surprised[checked]="toggleHeroesalso works - could someone explain this behavior?kapunahelewong commentedon Aug 1, 2019
Agreed, @dariobraun! I couldn't figure out how it was working both ways either. I've raised a flag on this one for engineering help, so we should get clarification soon.
rakeshTRF commentedon Aug 2, 2019
@dariobraun @kapunahelewong
Second, I am getting unchecked checkbox when I remove function - toggleHeroes() from ts file. It means this function giving true value to checkbox that's why it is checked on page load but as we know function is called on click. This is very surprised thing.
dariobraun commentedon Aug 21, 2019
Any input on this?
kapunahelewong commentedon Aug 22, 2019
Thanks for the bump, @dariobraun. Let me see if I can get some input. I think the right thing to do is change it. But why @Rakeshkohli gets the unchecked checkbox when removing the function, I'm not sure. I'll be back with some more info.
gkalpak commentedon Aug 22, 2019
Here is why it (kind of) works with
[checked]="toggleHeroes":What
[checked]="<expression>"does is evaluate<expression>and set the.checkedproperty of the input to the resulting value. Of course, the correct expression would beshowHeroes, which is a boolean property on the component instance.By using
toggleHeores(which is a method on the component instance), Angular will setinput.checkedtocomponentInstance.toggleHeroes. Since methods are functions and functions are truthy in JavaScript, the browser will consequently setinput.checkedtotrue. This will make the checkbox checked on load, which also happens to coniside withshowHeroesbeing initialized totrue. (I.e. ifshowHeroeswas set tofalsein the component instance, the checkbox would still be checked - which would not be our intention.)Now, upon clicking on the checkbox, the default browser behavior will kick in and toggle the checkbox's
checkedproperty. At the same time, Angular will evaluate the(click)handler expression (toggleHeroes()) and correctly toggleshowHeores, which is turn determines whether the heroes section will be shown or hidden (due to*ngIf="showHeroes").Finally, Angular will again evaluate the
[checked]expression, which will always evaluate to thetoggleHeroesmethod (note it evaluates to the method itself, it does not call the method). Since the value is the always the same as the previous value (thetoggleHeroesmethod), Angular will skip updating the.checkedproperty, leaving it to value currently set by the browser built-in click behavior.(Note that if Angular didn't have the optimization of skipping updating the property if the expression value hasn't changed since the last check, then Angular would always update
input.checkedto a truthy value and thus the checkbox would always be checked. So the example only works, because of this optimization, which basically makes[checked]="toggleHeroes"only take effect on page load.)I hope that (kind of) makes sense. Let me know if anything isn't clear.
And just to be clear, yes, the example is wrong and it should be
showHeroes, as already mentioned 😁rakeshTRF commentedon Aug 23, 2019
@gkalpak
And just to be clear, yes, the example is wrong and it should be showHeroes, as already mentioned ========> Okay.
gkalpak commentedon Aug 23, 2019
Reopening the issue, since the issue still needs to be fixed.
For reference, here is the line that needs fixing: https://github.com/angular/angular/blob/c624b14e8/aio/content/examples/http/src/app/app.component.html#L3
rakeshTRF commentedon Aug 23, 2019
@gkalpak
Great :)
docs: fix http example to use correct property (#32288)
docs: fix http example to use correct property (angular#32288)
angular-automatic-lock-bot commentedon Sep 23, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.