labyrinth
labyrinth

Reputation: 1164

Expression Value not getting updated in the view

I am writing a chrome extension using angularjs. For the same I have a controller as follows:

app.controller('PageCtrl', ['$scope', function ($scope) {
    this.pageTitle = "xyz";
    chrome.extension.sendMessage({ greeting: "PageDetails" },
        function (pageDetailResponse) {
            console.log(pageDetailResponse);
            if (pageDetailResponse.status) {
                this.pageTitle = pageDetailResponse.title;
                this.pageUrl = pageDetailResponse.url;
                this.pageFaviconUrl = pageDetailResponse.favIconUrl;
                status = true;
                console.log("Updated var pagetitle to "+this.pageTitle);
            }

        });
    }]);

The call chrome.extension.sendMessage in the above calls the function passed as argument asynchronously and I am sure it is called since I can see both the logs that I have printed in the function. On the html side, I have the following:

<body ng-controller="PageCtrl as page">
    <div ng-controller="TabsCtrl">
        <section>
            <ul>
                <li ng-class="{active:isActiveTab(tab.url)}">
                    <a href="" ng-click="tab=1">Save Page</a>
                </li>
                <li ng-class="{active:isActiveTab(tab.url)}">
                    <a href="" ng-click="tab=2">Snapshot</a>
                </li>
                <li ng-class="{active:isActiveTab(tab.url)}">
                    <a href="" ng-click="tab=3">Annotate</a>
                </li>
            </ul>
        </section>

        <div class="popup-body" ng-show="tab === 1">
            <h1>{{page.pageTitle}}</h1>
            <textarea></textarea>
            <div>
                <img ng-src="{{page.pageFaviconUrl}}" />
                <p>{{page.pageUrl}}</p>
            </div>
        </div>
    </div>
</body>

When the html is loaded, I can see value xyz (the value I have initialized it with). pagetitle does not reflect the new value assigned in the callback function. Am I making a wrong assumption here that if we change the title variable in the controller, the change is not reflected on the view?

Upvotes: 1

Views: 60

Answers (2)

Pankaj Parkar
Pankaj Parkar

Reputation: 136184

You need to run digest digest cycle manually by running $apply method on scope. As you are modifying scope outside angular context and also place var vm=this; outside function and use vm instead of this that will assure you are sharing same context inside the function.

More better way would be use $timeout to apply digest cycle that will run digest cycle but will not conflict with any currently running digest

Code

app.controller('PageCtrl', ['$scope', '$timeout', function($scope, $timeout) {
    var vm = this;
    vm.pageTitle = "xyz";
    chrome.extension.sendMessage({
            greeting: "PageDetails"
        },
        function(pageDetailResponse) {
            $timeout(function() {
                console.log(pageDetailResponse);
                if (pageDetailResponse.status) {
                    vm.pageTitle = pageDetailResponse.title;
                    vm.pageUrl = pageDetailResponse.url;
                    vm.pageFaviconUrl = pageDetailResponse.favIconUrl;
                    status = true;
                    console.log("Updated var pagetitle to " + vm.pageTitle);
                }
            })

        });
}]);

Upvotes: 1

Ren&#233; Wolferink
Ren&#233; Wolferink

Reputation: 3548

Because the function gets triggered outside of angular's control, you will have to manually apply the changes.

Wrap your function like this:

chrome.extension.sendMessage({ greeting: "PageDetails" },
    function (pageDetailResponse) {
        $scope.$apply(function() {
            console.log(pageDetailResponse);
            if (pageDetailResponse.status) {
                this.pageTitle = pageDetailResponse.title;
                this.pageUrl = pageDetailResponse.url;
                this.pageFaviconUrl = pageDetailResponse.favIconUrl;
                status = true;
                console.log("Updated var pagetitle to "+this.pageTitle);
            }
        });
    });
}]);

Upvotes: 1

Related Questions