AngularJS Factory variable value assignment breaks binding

642 Views Asked by At

It seems that when I assign a new value to a variable in my service/factory it breaks the binding and the controller stops updating the value UNLESS I call the $scope.verify function in my controller which merely prints the service object to the console, then the binding updates once. Am I assigning the value wrong in the skypeClient factory?

property.changed(function (_status) {
                state = _status;
                console.log("New State" + state);
            });

Ex. I execute $scope.signIn() and and the binding updates to signingIn but when the value changes to SignedIn (verified with console) the controller doesnt update to SignedIn unless I execute $scope.verify() for every change in skypeClient.state from there on after.

See code below:

Controller

controller('loginCntrl', function ($scope,skypeClient) {
    $scope.skypeClient = skypeClient;
    $scope.signIn = function () {$scope.skypeClient.signIn($scope.user, $scope.password)}
    $scope.signOut = function(){$scope.skypeClient.signOut()}
    $scope.verify = function () {
        console.log(skypeClient);
        console.log($scope.skypeClient);
    }
});

Service

.factory('skypeClient', function () {
        //Service Properties
        var client = new Skype.Web.Model.Application;
        var state = 'SignedOut';
        var property = property = client.signInManager.state;
        //Initialize Listeners
        var init = function () {
            client.signInManager.state.when('SignedIn', function () {
                console.log('Signin:' + state); // This outputs the correct value
            });
            property.changed(function (_status) {
                state = _status;                  //<--WHERE VALUE IS UPDATED
                console.log("New State" + state);
            });
           }
        //Signin Function
        var signIn = function (username, password) {
           client.signInManager.signIn({
                username: username,
                password: password
            }).then(function () {console.log('LoggedIn');});
        }
        var signOut = function () {
            client.signInManager.signOut()
            .then(function () {
                this.isSignedIn = false;
            }, function (error) {
                this.erros.push(error);
                this.errorCount++;
            });
        }
        init();
        return {
            signIn: signIn,
            signOut, signOut,
            state: function(){return state}
        }
   });

HTML

(Current Signin State: {{skypeClient.state()}} )
1

There are 1 best solutions below

2
On

Let me try this out.

If you can, try to make the state a variable on the scope where it needs to show up in the binding.

Controller

controller('loginCntrl', function ($scope,skypeClient) {
    ...
    $scope.state = skypeClient.state();
    ...
});

HTML

(Current Signin State: {{ state }} )

Now, in your controller, you can add a $watch to the state variable from the skypeClient. If I'm correct, things should update with much more success.

Controller (again)

controller('loginCntrl', function ($scope,skypeClient) {
    ...
    $scope.state = skypeClient.state();
    ...
    // Add this $watch

    $scope.$watch(skypeClient.state, function (newValue, oldValue) {
        if (newValue !== oldValue) {
            $scope.state = newValue;
        }
    });
});