Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(select): do not break when removing the element (e.g. via ngIf) #15468

Closed
wants to merge 2 commits into from

Conversation

gkalpak
Copy link
Member

@gkalpak gkalpak commented Dec 3, 2016

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix.

What is the current behavior? (You can also link to an open issue here)
When removing <option> elements, we schedule some operations on the ngModelCtrl. For performance reasons, these operation are scheduled to be run as a post-digest operation. If the <select> element happens to be removed as well (and its scope destroyed), an error may be thrown due to certain values not being available on the $scope.
See #15466.

What is the new behavior (if this is a feature change)?
Nothing breaks.

Does this PR introduce a breaking change?
No.

Please check if the PR fulfills these requirements

Other information:
Fixes #15466.

@@ -76,9 +76,11 @@ var SelectController =
}
};

var scopeDestroyed = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use the $$destroyed property of the scope rather than tracking the state with a sentinel var?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I could. But since we were already having a $destroy callback I opted for using that instead of the $$destroy as it seems unnecssary. Can go either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If $$destroyed would work then I would prefer that. It is one less thing to store in memory and keep track of in maintenance of the code.

@Narretz
Copy link
Contributor

Narretz commented Dec 5, 2016

Does the app actually break when the select is removed, or does it just throw? I mean, is there some cleanup that is not performed? I think the commit message should reflect that more precisely.

@gkalpak
Copy link
Member Author

gkalpak commented Dec 5, 2016

@Narretz, not sure what you mean. An error is thrown in the middle of a digest. Whether that breaks an app depends on what was going on during that digest, what watchers were skipped due to the error etc.

@gkalpak
Copy link
Member Author

gkalpak commented Dec 5, 2016

BTW, the particular error in #15466 is caused by this line: When a previously selected option element is destroyed, we schedule to re-read the select's value asynchronously. Since destroying the select itself also destroys its option children, it triggers this check (which then fails because the scope has been destroyed already.
But similar problems would arise whenever we call scheduleViewValueUpdate() and the select is destroyed before the $$postDigest phase, so guarding against it inside scheduleViewValueUpdate's $postDigest callback seems appropriate.

@Narretz
Copy link
Contributor

Narretz commented Dec 5, 2016

@gkalpak In the middle of a digest? It throws in $$postDigest, no?

@gkalpak
Copy link
Member Author

gkalpak commented Dec 5, 2016

Yeah, sorry, I meant $$postDigest. So, whether the app breaks, depends on what tasks are still pending in the postDigestQueue 😁

@gkalpak
Copy link
Member Author

gkalpak commented Dec 5, 2016

Aha, I see your point. I just realized it only breaks if the $exceptionHandler rethrows. I will change the wording to "not throw".

@gkalpak gkalpak force-pushed the fix-ngModel-when-destroyed branch from f68232b to 50755af Compare December 5, 2016 19:24
@petebacondarwin
Copy link
Contributor

LGTM

@gkalpak gkalpak closed this in 7a667c7 Dec 6, 2016
@gkalpak gkalpak deleted the fix-ngModel-when-destroyed branch December 6, 2016 11:04
ellimist pushed a commit to ellimist/angular.js that referenced this pull request Mar 15, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1.6.0-rc.2: ng-if on select component with an ng-model produces "Cannot read property '$$phase' of null" error
5 participants