Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$scope value doesn't get updated in other controller

I'm having a problem updating a value on my view. Let me show you my code with a little bit explanation of what is going on. I know the code is a litte bit messy since i have tried many code combinations right now.

I'm having this accCtrl controller

controllers.accCtrl = function($scope, sessionFactory){
    sessionFactory.isLoggedIn().then(function(data){
        console.log(data.logged_in);
        $scope.loggedIn = data.logged_in;
    });
    $scope.logOut = function(){
        sessionFactory.logOutUser().then(function(data){
            $scope.loggedIn = data.logged_in;
        });
    }
}

Console log out put is false and this variable $scope.loggedIn controls my html by showing or hiding login, register, my profile and log out buttons

<div ng-controller="accCtrl">
    {{loggedIn}}
        <ul>
        <li ng-hide="loggedIn">
            <a href="#/login">
                <b>Login</b>
            </a>
        </li>
        <li ng-hide="loggedIn">
            <a href="#/register" >
                <b>Register</b>
            </a>
        </li>
        <li ng-show="loggedIn" >
            <a href="#/my_profile">
                <b >My profile</b>
            </a>
        </li>
        <li ng-show="loggedIn"> 
            <a ng-click="logOut()">
                <b>Log out</b>
            </a>
        </li>
    </ul>
</div>

Now user tries to login so he click on login button, and login form is shown. This login functionality is written in loginCtrl

    controllers.loginCtrl = function($scope, $http, $location, $timeout, sessionFactory){
    $scope.loginUser = function () {
        $http({
            method: 'POST',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/login',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data : $.param({
                username : $scope.username,
                password : $scope.password
            })
        }).success(function(data){
                sessionFactory.isLoggedIn().then(function(data){
                    $scope.loggedIn = data.logged_in;
                });
                window.location.href="/#/home";
        });
    };
}

After he successfully logs in, he or she is redirected on home page, but the problem is that $scope.loggedIn variable in account controller isn't updated even doe that console.log(data.logged_in) in loginCtrl is seted as true

If user pressed log out button, everything works ok again, since i'm calling function inside accCtrl. So the only problem is when users logs in, because he is doing this in another controller.

Also here is my sessionFactory in case u wan't to see how i check if user is logged

app.factory('sessionFactory', ['$http', '$location', function($http, $location){
    var factory = {};

    factory.logOutUser = function(){
        return $http({
            method: 'GET',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/logout'
        }).then(function successCallback(response){
            return response.data;
        },function errorCallback(response) {
            console.log('error logging out: ' + response);
        });
    }
    factory.isLoggedIn = function(){
        return $http({
            method: 'GET',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/isLoggedIn'
        }).then(function successCallback(response){
            console.log(response.data);
            return response.data;
        },function errorCallback(response) {
            console.log('Checking login failed: ' + response);
        });
    }

    return factory;
}]);

my app.js

var app = angular.module('app', ['ngRoute', 'ngAnimate', 'ui.sortable', 'ngFileUpload'])
app.config(function($routeProvider){
    $routeProvider.
    when('/', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
    when('/home', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
    when('/contact', {controller:'contactCtrl', templateUrl:'app/templates/contact.html'}).
    when('/about_us', {controller:'aboutUsCtrl', templateUrl:'app/templates/aboutUs.html'}).
    when('/cookies', {controller:'cookiesCtrl', templateUrl:'app/templates/cookies.html'}).
    when('/faqs', {controller:'faqsCtrl', templateUrl:'app/templates/faqs.html'}).
    when('/register', {controller:'registerCtrl', templateUrl:'app/templates/register.html'}).
    when('/login', {controller:'loginCtrl', templateUrl:'app/templates/login.html'}).
    when('/my_profile', {controller:'myProfileCtrl', templateUrl:'app/templates/myProfile.html'}).
    when('/trade/:param1', {controller:'tradeCtrl', templateUrl:'app/templates/trade.html'}).
    when('/user/:param1', {controller:'userCtrl', templateUrl:'app/templates/user.html'}).
    when('/swap/:param1', {controller:'subCategoriesCtrl', templateUrl:'app/templates/subCategories.html'}).
    when('/swap/:param1/:param2', {controller:'products', templateUrl:'app/templates/products.html'}).
    when('/swap/:param1/:param2/:param3', {controller:'product', templateUrl:'app/templates/product.html'}).
    otherwise({ redirectTo: '/home'});
  });

I probably have to implement some watch or some similar function, but i really don't know how so i would appreciate if you help me out.

Explained in pictures

Login and register button is displayed Working as expected

User clicks on login button and logins successfully, but buttons are not refreshed, because action is happening in loginCtrl, but buttons are in accCtrl

enter image description here

After hitting f5 in browser, buttons get properly updated in accCtrl.

enter image description here

TLTR

Once user logs in in loginCtrl i have to update $scope.loggedIn value in accCtrl

If you need any additional information, please let me know

like image 968
Valor_ Avatar asked Mar 13 '23 05:03

Valor_


1 Answers

The problem occured because the controller in angularjs are initialized only once, unless you set it to reinitialize. Try alerting something in the accCtrl, it will alert only once even if you navigate to that page multiple times. Hitting ctrl+f5 worked because it reinitialized your controller. You can simply use $window.location.reload() to reinitialize the controller. What $window.location.reload() does is it not only reloads your controller but your services as well. Since, you are using ngRoute, all i can think to reinitialize your controller is using $window.location.reload();

.success(function(data){
                sessionFactory.isLoggedIn().then(function(data){
                    $scope.loggedIn = data.logged_in;
                });
                window.location.reload(); //the only workaround i could find with ngroute as for now.
                window.location.href="/#/home";
        });

However using ui.Router i.e.,$stateProvider provides you the option of reinitializing your controller only which is as following.

.state('home', {
    url: '/home',
    templateUrl: 'templates/home.html',
    controller: 'accCtrl',
    reload: true //will reload controller when state is being access
});

$state.transitionTo($state.current, {}, { reload: true, inherit: true, notify: true });

and

$state.go('.', null, { reload: true });

will resolve the issue of reinitializing the controller which seems to be the problem for your question as for now.

like image 108
Sunil Lama Avatar answered Mar 16 '23 00:03

Sunil Lama