$scope.myVariable not updated in controller for angular-ui bootstrap modal

All we need is an easy explanation of the problem, so here it is.

In my view I have an input, a span and a button like so:

<script type="text/ng-template" id="myTemplate.html">
  <input type="text" ng-model="phoneNumber">
  <span>{{ phoneNumber}}</span>
  <input type="button" ng-click="click()">
</script>

When typing in the textbox, the content of the span updates as expected reading. But when clicking the button, phoneNumber has not updated inside the controller:

app.controller('myPopopCtrl', ['$scope', '$modalInstance',
  function ($scope, $modalInstance) {
      $scope.phoneNumber= '';    

      $scope.click = function() {
        alert($scope.phoneNumber); // alerts only ''
      };

Is there some newbe mistake you can make in angular which makes stuff not updating on the $scope inside a controller?

Are there some $scope issues with the angular-ui modal I need to be aware of?

Edit:

It seems like phoneNumber gets created in 2 scopes. One time in the scope at the blue arrow which where phoneNumber: '' and once in the child scope at the red arrow. The view uses the phoneNumber in the child scope and the controller uses the phoneNumber in the parent scope…

enter image description here

Why are two scopes created?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

ng-include creates a new scope. So pass a object instead of string

$scope.phone={number:null}

The template then looks like

<script type="text/ng-template" id="myTemplate.html">
  <input type="text" ng-model="phone.number">
  <span>{{ phone.number}}</span>
  <input type="button" ng-click="click()">
</script>

Look at this wiki to understand the issues with prototypal inheritance.

Method 2

Had the same problem and after a few experiments I’ve settled on writing

<input type="text" ng-model="$parent.phoneNumber">

This way input is bound to the blue scope, which is exactly what you wanted.

Other way is to initialise phoneNumber with a true-ish value. Try $scope.phoneNumber= '123'; – worked fine for me.

Angular seems to walk up the scope tree looking for an attribute to bind to. If nothing’s found – it binds to the inner-most scope, red scope in your pic.
As other answer suggests – this red scope is created by ng-include, as a child of controller’s $scope.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply