Property in ng-model not matching $scope.property in controller

9,018 views
Skip to first unread message

Martijn Vos

unread,
Dec 13, 2013, 10:41:24 AM12/13/13
to ang...@googlegroups.com
I'm utterly stumped about this one:

I've got a property, pageSize, that is originally set in the controller, but can be updated through a select box. When I change the select box, data-bindings in the view get updated, but not the one in the controller's scope, and I don't understand why.

Everything else works fine. I've got only one controller that does everything else it's supposed to do. I'm calling update() from ng-change which works fine. And in the update(), I log the value of $scope.pageSize, but that value never changes, despite the {{pageSize}} just above my select showing the new value.

How is this possible?

HTML:
            {{pageSize}}
            <select name="pageSize" id="pageSize" ng-model="pageSize" ng-change="update();">
                <option value="5">5</option>
                <option value="10">10</option>
                <option value="25">25</option>
                <option value="50">50</option>
            </select>

Controller:
    $scope.pageSize = 5;

    $scope.update = function() {
        console.log("pageSize = "+$scope.pageSize);
        reviewService.fetch({
            pageSize: $scope.pageSize,
        }).success(function(data, status) {
            console.log("success!");
            $scope.reviewData = data.d;
            $scope.nrOfPages = Math.ceil($scope.reviewData.summary.ReviewCount / $scope.pageSize);
        }).error(function(data, status) {
            console.log("error!");
            $scope.error = true;
        });
    }
    $scope.update();

So to be clear:
* $scope.update() gets called correctly by ng-change.
* the log($scope.pageSize) always logs '5'.
* {{pageSize}} shows the value I selected.


mcv.

Daniel Tabuenca

unread,
Dec 13, 2013, 11:23:00 AM12/13/13
to ang...@googlegroups.com
Usually this is due to another directive in-between your ng-controller and your input that is creating a new scope. When the select writes out it value, it will write it up to the most recent scope, so it would write it to this scope rather than the parent that is further away. 

The best practice is to never bind directly to a variable on the scope in an `ng-model`, this is also known as always including a "dot" in your ngmodel. For a better explanation of this, check out this video from John:

Martijn Vos

unread,
Dec 13, 2013, 11:38:16 AM12/13/13
to ang...@googlegroups.com
Thanks! That works.

Still, I don't understand where this new scope is coming from. I've got only one controller, and the only directives in between that and my select, are an ng-hide on the same element that has my controller, and the ng-model and ng-change on my select.

So did the ng-hide give me a new scope? I could test it by removing it, but for now I'm happy that this works. And in a way it's actually nicer to have all these paging and sorting related parameters together in the same object.


mcv.



--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Daniel Tabuenca

unread,
Dec 13, 2013, 12:09:27 PM12/13/13
to ang...@googlegroups.com
Could you post your template?

Daniel Tabuenca

unread,
Dec 13, 2013, 12:13:14 PM12/13/13
to ang...@googlegroups.com
Also you can use the chrome batarang extension to see where all your scopes are and solve the mystery.

Martijn Vos

unread,
Dec 14, 2013, 6:05:08 AM12/14/13
to ang...@googlegroups.com
There's quite a bit of html to post it all here. There's quite a lot of directives all over the page, but none of them above this select in the DOM tree (other than that ng-hide and the controller itself). The only explanation would be in ng-hide creates a scope of its own, but that would seem unnecessary and inconvenient. Not every directive automatically imposes its own scope on everything below it, does it?

I may have a look at that batarang extension. It sounds very useful. But that would be mostly to understand scope a bit better. The "dot" notation fixes my problem very well, and makes it all better structured and cleaner too, so I consider that problem solved.


Met vriendelijke groet,

Martijn Vos
Vosdev

in...@vosdev.com
06-43872118

Daniel Tabuenca

unread,
Dec 14, 2013, 1:18:02 PM12/14/13
to ang...@googlegroups.com
ng-hide should definitely not be creating any scope, but if dot notation fixes the problem then that's a very telling sign that there is, in fact, some scope being created by something in between. Batarang should be able to tell you exactly what the scopes are and what data each scope contains. You could also look at the scopes in your dom. Angular adds ng-scoppe class to each element where it has created a scope, but you won't be able to see the actual scope data.

Martijn Vos

unread,
Dec 17, 2013, 5:28:39 AM12/17/13
to ang...@googlegroups.com
I notice all my ng-includes have an ng-scope class. I hadn't expected ng-include to do anything more than simply include the html, and completely forgot that they are also directives. And directives with their own scope, apparently. So that explains it.

SHIVANG SANGHI

unread,
Jun 5, 2014, 8:03:27 AM6/5/14
to ang...@googlegroups.com, mcv...@gmail.com
I have updated the code...Check this..
HTML:
            {{pageSize}}
            <select name="pageSize" id="pageSize" ng-model="pageSize" ng-change="update(pageSize);">
                <option value="5">5</option>
                <option value="10">10</option>
                <option value="25">25</option>
                <option value="50">50</option>
            </select>

Controller:
    $scope.pageSize = 5;

    $scope.update = function(pageSize) {
           $scope.pageSize = pageSize;

gerul

unread,
Feb 12, 2015, 8:02:34 AM2/12/15
to ang...@googlegroups.com, mcv...@gmail.com
SHIVANG SANGHI 
I just created an account to say thank you for your idea of updating $scope. You saved my ass... THANK YOU 

Bakul Patel

unread,
Feb 22, 2018, 8:09:56 AM2/22/18
to Angular and AngularJS discussion
Hi Shivang,
This was really really helpful, saved lot of time!!!

Thanks,
Bakul

akib deraiya

unread,
Aug 28, 2019, 10:50:48 PM8/28/19
to Angular and AngularJS discussion
This works pretty cool man. 
Thanks i try to found on internet but you save my lots of time.

Thanks
Reply all
Reply to author
Forward
0 new messages