1

I have the following on an Angular controller:

application.controller('ImageController', function ImageController($scope, ImageService) {

  $scope.model = {
    images: [],
    multiple: false
  }

  $scope.$watch('model.multiple', function (newVal, oldVal) {
    console.log(newVal);
    console.log(oldVal);
  });

}

I need to get the $scope.model.multiple value from an hidden input.

The hidden input value is filled from server side. So for testing I have:

<input type="hidden" data-ng-model="model.multiple" data-ng-value="true" />

When I run my code both newVal and oldVal are false ... Why?

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

4 Answers4

1

If you're populating the value of an input hidden server-side and wants it to become available in Angular, do it the whether in the Angular way, loading a JSON with the value or, if you don't have access to back-end or if you don't want to change your code a lot, render the template with an id like:

<input type='hidden' id='hiddenValue' value='xx(server-side)xx'>

And then inside the controller put something like:

$scope.value = document.getElementById('hiddenValue');
Marcos Sandrini
  • 400
  • 2
  • 10
0

I don't think ngValue does what you think it does. It is meant for use with Options (in Selects) and for Radio Buttons. See docs here.

Short answer: The values in your $scope.$watch are false because you set $scope.model.multiple to false in the controller and a hidden input in a view doesn't get bound to the model as you hoped it would.

In your code I think you are trying to set model.multiple's value in your view for no reason, and in a way that is not possible.

It is my opinion that you should be setting the value to true in the controller. I don't see any reason why you would need it to be handled within a hidden input. You mention that it is coming "from the server", but the view is rendered by AngularJS - not some other server.

The purpose of the two-way binding on inputs is so that user edits will be reflected in your model. There doesn't appear to be any binding at all on hidden inputs since they are not user editable. Hidden inputs are meant for form submissions, and Angular doesn't do those. Forms serve a different purpose in Angular.

Check out this Plunk to see that hidden inputs don't impact the model. View:

<body ng-controller="MainCtrl">
  <input type="hidden" ng-model="model.multiple" ng-value="true" value="true" />
  <input type="hidden" ng-model="model.test" />Hidden inputs have no impact on the model.
  <br>That's why this is blank: '{{model.test}}'
</body>

Controller:

app.controller('MainCtrl', function($scope) {
  $scope.model = {
    images: [],
    multiple: false
  }

  $scope.$watch('model.multiple', function(newVal, oldVal) {
    console.log('New: ' + newVal);
    console.log('Old: ' + oldVal);
  });
});
Michael Oryl
  • 20,856
  • 14
  • 77
  • 117
  • I tried that and both newVal and oldVal are undefined – Miguel Moura Feb 10 '15 at 13:44
  • @MiguelMoura I've updated the answer completely. It just appears that you can't impact the model through a hidden input, and I imagine that's not really what you want (or should) do. – Michael Oryl Feb 10 '15 at 14:03
  • I think I am going for window ... Basically I need to use, in my controller, a server side variable value ... – Miguel Moura Feb 10 '15 at 14:43
  • @MiguelMoura So you are saying that your http server is going to embed a value into the HTML views that it serves up as the Angular app? If that's the case, the is not what you need. I would encourage you to accept an answer here (the answer is it is not possible) and then post a question that focuses on how to get a server side value into your application. There are a number of ways to do that that I believe would work much better for you. I'd be happy to work on such a question if you posted it. – Michael Oryl Feb 10 '15 at 14:47
0

Instead of ngValue directive,you can use ngInit directive.Here is how you can do that.

ng-init="model.multiple=true"

Hazarapet Tunanyan
  • 2,809
  • 26
  • 30
0

You can set the value as a global variable like

<script>
   window.model = {multiple: true};
</script>

then in your controller add $window and set the value like this

application.controller('ImageController', function ImageController($scope,  $window, ImageService) {

$scope.model = {
    images: [],
    multiple: $window.model.multiple
   }

as described here Angular js init ng-model from default values

Community
  • 1
  • 1
etoisarobot
  • 7,684
  • 15
  • 54
  • 83