0

I have the following code in my controller:

appControllers.controller('myCtrl', [ '$scope',
function($scope) {
    $scope.timeFreeze = false;

    $scope.ws = new WebSocket("ws://localhost:8080/ws");

    $scope.ws.onopen = function() {
        $scope.ws.send('{...}');
    };

    $scope.ws.onmessage = function (evt) {
        var received_msg = JSON.parse(evt.data);
        //...do something with the data...
        console.log($scope.timeFreeze); // This is ALWAYS false!!! Why?
        if ( $scope.timeFreeze === false) {
            $scope.$apply();
        } else {
            console.log("Frozen!"); // This never runs!!!
        }
    };

    $scope.ws.onclose = function() {
        console.log("Connection is closed...");
    };
}

]);

and in my html I have:

<div>
    <label>Freeze?</label>
    <input type="checkbox" ng-model="timeFreeze"/>
</div>

What is meant to happen is that when the checkbox is ticked, the code should output "Frozen!" in the console. Unfortunately this code is NEVER run! The $scope.timeFreeze is always false despite me setting the ng-model for the checkbox.

10
  • 2
    Try using dot notation. Something like ng-model="socket.timeFreeze" and $scope.socket.timeFreeze. Commented Feb 28, 2015 at 16:25
  • 1
    +1 to jeff. Your input must be inside an ng-repeat or ng-if or any other directive that creates its own child scope. So you're setting the value of the timeFreeze attribute of the child scope instead of modifying the controller scope. Commented Feb 28, 2015 at 16:28
  • @JBNizet Well its under the ng-controller="myCtrl" implicitly as I am angular routes Commented Feb 28, 2015 at 16:32
  • 3
    Yes, but ng-if/ng-repeat are also under the scope of myCtrl, and create their own child scope. Show us your complete html if you want us to spot the bug exactly. But the fix of jeff should work fine. Use $scope.time = {freeze: false }; in your controller, and use ng-model="time.freeze" in your view. Commented Feb 28, 2015 at 16:35
  • 1
    The 2-way binding for primitive does not work as people expect. The child value does not does propagates up. This is a fundamental issue with JavaScript, not of angular. You can learn more about it here: github.com/angular/angular.js/wiki/Understanding-Scopes Commented Feb 28, 2015 at 19:11

1 Answer 1

1

Posting the answer so it can be marked:

Try using dot notation. Something like ng-model="socket.timeFreeze" and $scope.socket.timeFreeze. JB Nizet used a better naming convention so I'm gong to borrow from him:

In your controller:

$scope.time = {freeze: false };

In your view:

<input type="checkbox" ng-model="time.freeze">
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.