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

ngChange for <select> after 1.3.0 rc0 now fires when value is undefined #9918

Closed
ghost opened this issue Nov 5, 2014 · 4 comments
Closed

Comments

@ghost
Copy link

ghost commented Nov 5, 2014

In our application prior to 1.3.0 rc1 the ng-change event was not being fired when our was first displayed. Now it is being fired and when we check the value of the variable used for model then it has a value of undefined. This happens only when a form is first displayed. All versions including and prior to rc0 are okay. All versions after fire the ngChange when the model value is still undefined. Here is the code that we are using: <select ng-model="home.modal.topicId" ng-change="ctrl.modalTopicChanged()" ng-options="item.id as item.name for item in home.modal.option.topics.data" ng-required="true"> <option style="display: none;" value="">Select Topic</option> </select> Producing a stack trace when the function code attempts to use an undefined value for home.modal.topicId. This happens only for 1.3.0 rc1 and later versions: TypeError: Cannot read property 'dataMap' of undefined at AdminProblemController.modalTopicChanged (http://127.0.0.1:17315/Content/app/admin/controllers/ProblemController.js:109:114) at $parseFunctionCall (http://127.0.0.1:17315/Scripts/angular.js:11387:18) at Scope.$get.Scope.$eval (http://127.0.0.1:17315/Scripts/angular.js:13276:28) at http://127.0.0.1:17315/Scripts/angular.js:19888:13 at http://127.0.0.1:17315/Scripts/angular.js:19499:9 at forEach (http://127.0.0.1:17315/Scripts/angular.js:331:20) at $$writeModelToScope (http://127.0.0.1:17315/Scripts/angular.js:19497:5) at writeToModelIfNeeded (http://127.0.0.1:17315/Scripts/angular.js:19490:14) at http://127.0.0.1:17315/Scripts/angular.js:19484:9 at validationDone (http://127.0.0.1:17315/Scripts/angular.js:19420:9) I checked and it would appear there were significant changes to a code area in rc1 that I assume are now causing us this problem. In particular there were many changes around the area of code below: ** * @ngdoc method * @name ngModel.NgModelController#$commitViewValue * * @description * Commit a pending update to the `$modelValue`. * * Updates may be pending by a debounced event or because the input is waiting for a some future * event defined in `ng-model-options`. this method is rarely needed as `NgModelController` * usually handles calling this in response to input events. */ this.$commitViewValue = function() { var viewValue = ctrl.$viewValue; $timeout.cancel(pendingDebounce); // If the view value has not changed then we should just exit, except in the case where there is // a native validator on the element. In this case the validation state may have changed even though // the viewValue has stayed empty. if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) { return; } ctrl.$$lastCommittedViewValue = viewValue; // change to dirty if (ctrl.$pristine) { ctrl.$dirty = true; ctrl.$pristine = false; $animate.removeClass($element, PRISTINE_CLASS); $animate.addClass($element, DIRTY_CLASS); parentForm.$setDirty(); } this.$$parseAndValidate(); }; this.$$parseAndValidate = function() { var parserValid = true, viewValue = ctrl.$$lastCommittedViewValue, modelValue = viewValue; for(var i = 0; i < ctrl.$parsers.length; i++) { modelValue = ctrl.$parsers[i](modelValue); if (isUndefined(modelValue)) { parserValid = false; break; } } if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) { // ctrl.$modelValue has not been touched yet... ctrl.$modelValue = ngModelGet(); } var prevModelValue = ctrl.$modelValue; var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid; if (allowInvalid) { ctrl.$modelValue = modelValue; writeToModelIfNeeded(); } ctrl.$$runValidators(parserValid, modelValue, viewValue, function() { if (!allowInvalid) { ctrl.$modelValue = ctrl.$valid ? modelValue : undefined; writeToModelIfNeeded(); } }); function writeToModelIfNeeded() { if (ctrl.$modelValue !== prevModelValue) { ctrl.$$writeModelToScope(); } } }; this.$$writeModelToScope = function() { ngModelSet(ctrl.$modelValue); forEach(ctrl.$viewChangeListeners, function(listener) { try { listener(); } catch(e) { $exceptionHandler(e); } }); }; I would like to know if this is intended functionality. I see no mention of this in the changes so I assume it may be a change that was not intended but that has not been caught in testing.

@ghost
Copy link
Author

ghost commented Nov 5, 2014

I think this is related to #9867

@caitp
Copy link
Contributor

caitp commented Nov 5, 2014

I don't think this is related to #9867, but you should create a reproduction on http://plnkr.co so we can take a look. #9867 has to do with a defined model value being transformed into a string, therefore being considered changed, even though the user didn't touch it.

@ghost
Copy link
Author

ghost commented Nov 17, 2014

Please see this post where another user was able to duplicate the problem:

http://stackoverflow.com/questions/26731921/problems-with-ngchange-for-select-after-1-3-0-rc0

@Narretz
Copy link
Contributor

Narretz commented Nov 25, 2014

This is fixed in 1.3.4 :)

@Narretz Narretz closed this as completed Nov 25, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants