1

I am trying to send a request to a php file from one controller in angular and getting the response. I stored the response in a rootScope variable which is initialized in the controller.run() method with 0.

Now I am trying to use the updated rootScope in another controller in order to display the response from the php page. But the rootScope is not getting updated and it is still showing 0.

Here is my code.

The following is the run method where the rootScope is initialized

adminController.run(function ($rootScope) {
    $rootScope.n = 0;
});

The following is the code for controller 1 where I am requesting a response from the php page and updating the rootScope variable.

adminController.controller('adminLoginController', function($scope,$rootScope,$http,$window) {

    $scope.loginCheck = function(event,user){
        var request = $http({
            method: "post",
            url: "../_/php/loginCheck.php",
            headers: { 'Content-Type': 'application/x-www-form-urlencoded'     }
        });
        request.success(function (data) {
            $rootScope.n=data;
            $rootScope.$apply();
            $window.location.href = 'admin.html#admin_home';       
        });
    }
});

Here is the code for my second controller where I am utilizing the rootScope variable. Here the problem comes as the rootScope is not getting updated and displaying me only the 0 with which it is initialized.

adminController.controller('adminHomeController', function($scope,$rootScope,$http,$window) {
    $scope.uname=$rootScope.n;
    alert($scope.uname);
});

Can some one let me know where I am going wrong.

Baradwaj Aryasomayajula
  • 1,184
  • 1
  • 16
  • 42
  • 1
    `$rootScope.$apply();` Is not needed, a digest cycles runs automatically with `http`. Any console errors? Try putting a console log in your `.run` to see if it's rerunning on nav? – Dylan Watt Jan 27 '16 at 16:00
  • I think your controller load first then **$rootScope** value update. can you show more hint – Sandeep Jan 27 '16 at 16:02
  • @DylanWatt I tried logs in both the run method and the success method of controller 1. It is not showing the log of the controller 1. And yes the run method is running again... – Baradwaj Aryasomayajula Jan 27 '16 at 16:58
  • @BaradwajAryasomayajula : If the suggestions solved your problem, you can mark mark any answer as accepted which you think best suited your requirement – Pratap A.K Jan 28 '16 at 03:45

3 Answers3

3

Your problem sounds like a timing issue. To communicate between controllers with $rootScope, you can set up an event to listen for changes.

Update root scope:

$rootScope.$broadcast('n', data);

Listen for changes:

$rootScope.$on('n', function (event, data) {
    //do something with new value 'data'
});
aw04
  • 10,857
  • 10
  • 56
  • 89
  • a reason for the downvote? it would be helpful not only to myself but anyone who reads this anwser – aw04 Jan 28 '16 at 14:52
1

HTML

<body ng-app="adminController">

<div ng-controller="adminLoginController">
        <button ng-click="loginCheck()">loginCheck</button>
    </div>

    <div ng-controller="adminHomeController">
    <button ng-click="getval()">getVal</button>
        rootscope val {{uname}}
    </div>
</body>

controllers

var app = angular.module('adminController', []);

app.run(function ($rootScope) {
    alert("run");
    $rootScope.n = 0;
});

adminController.controller('adminLoginController', function($scope,$rootScope,$http,$window) {

    $scope.loginCheck = function(){
        alert("Inside loginCheck");
        $rootScope.n = 1;      
    }
});

adminController.controller('adminHomeController', function($scope,$rootScope,$http,$window) {

    $scope.getval = function() {
        $scope.uname = $rootScope.n;
    } 
});

If both of your controllers instantiates at the same time, then you need to use even based notification as suggested by @aw04 using $broadcaste,$on and $emit.

Pratap A.K
  • 4,337
  • 11
  • 42
  • 79
1

Put a $watch on the variable

adminController.controller('adminHomeController', function($scope,$rootScope,$http,$window) {
    $scope.$watch(
        function watchFn(){ return $rootScope.n; },
        function listener(newValue, oldValue) {
            $scope.uname=newValue;
        }
    );
});

For more information, see AngularJS $watch API Reference


Keep in mind that it is not wise to clutter $rootScope with data. Persistent data is better kept in a service.

app.factory("LoginCheck", function($http) {
    var n = 0;
    var request;
    function getN() { return n; };
    function setN(newN) { n = newN; return n; } 
    function getRequest { return request; };
    function check(user) { 
        request = $http({
            method: "post",
            url: "../_/php/loginCheck.php",
            headers: { 'Content-Type': 'application/x-www-form-urlencoded'     }
        });
        var derivedRequest = request.then(function (response) {
            setN(response.data);
            //return for chaining
            return response;
        });       
        request = derivedRequest;
        return request;
    };
    return {
        getN: getN,
        setN: setN,
        getRequest: getRequest,
        check: check
    };
});

Then in your LoginController:

adminController.controller('adminLoginController', function($scope,$window,LoginCheck) {

    $scope.loginCheck = function(event,user){
        var req = LoginCheck.check(user);
        req.then(function (response) {
            $window.location.href = 'admin.html#admin_home';       
        }).catch(function (errorResponse) {
            console.log(errorResponse.status);
        });
    };
});

In your HomeController:

adminController.controller('adminHomeController', function($scope,LoginCheck) {
    if ( LoginCheck.getN() ) {
        $scope.uname = LoginCheck.getN();
    } else {
        LoginCheck.getRequest().then( function() {
            $scope.uname = LoginCheck.getN();
        });
    }; 
});
georgeawg
  • 48,608
  • 13
  • 72
  • 95