On hard refresh, $rootScope disappears and cannot

2019-09-01 02:14发布

问题:

I am using $rootScope to always access the current logged in user. When the user submits a new meal into the system the meal attributes are stored plus the user id who submitted them.

This works, but the moment I hard refresh my browser, the $rootScope.user object disappears.

How do I prevent that?

In app.js I have:

$rootScope.user;

Here's what happens when the user logs in:

Auth.$onAuth(function (user) {
                if (user === null) {
                    console.log("Not logged in yet");
                } else {
                    console.log("Logged in as", user.uid);
                }
                $rootScope.user = user;
        });

Then, when the user accesses the AddMeal page, within the AddCtrl we have:

var firebaseObj = new Firebase("https://myapp.firebaseio.com/courses/");
    var fb = $firebaseArray(firebaseObj);
console.log($rootScope.user)

$scope.newMeal = {
    name: "",
    price: "",
    ingredients: "",
    description: "",
    category: "",
    cuisine: "",
    userID:""
};

$scope.submitMeal = function () {
    if (angular.equals({}, $scope.newMeal)) {
        alert("Your form is empty");
        $rootScope.notify('Your form is empty')
    } else {
        console.log($scope.newMeal);
        var name = $scope.newMeal.name;
        var price =  $scope.newMeal.price;
        var ingredients= $scope.newMeal.ingredients;
        var description = $scope.newMeal.description;
        var category= $scope.newMeal.category;
        var cuisine= $scope.newMeal.cuisine;

        fb.$add({
            name: name,
            price: price,
            ingredients: ingredients,
            description: description,
            category: category,
            cuisine: cuisine,
            userID: $rootScope.user.uid
        }).then(function(ref) {
            $scope.newMeal = {};
            console.log(ref);
        }, function(error) {
            console.log("Error:", error);
        });

        $rootScope.notify('New meal has been added!')
    }

Here is my run function in app.js:

.run(function ($ionicPlatform, $rootScope, $firebaseAuth, $firebase, $window, $ionicLoading) {
        $ionicPlatform.ready(function () {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
                cordova.plugins.Keyboard.disableScroll(true);

            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }

            $rootScope.show = function(text) {
                $rootScope.loading = $ionicLoading.show({
                    content: text ? text : 'Loading..',
                    animation: 'fade-in',
                    showBackdrop: true,
                    maxWidth: 200,
                    showDelay: 0
                });
            };

            $rootScope.hide = function() {
                $ionicLoading.hide();
            };

            $rootScope.notify = function(text) {
                $rootScope.show(text);
                $window.setTimeout(function() {
                    $rootScope.hide();
                }, 1999);
            };

            $rootScope.user;

        });
    })

回答1:

AngularJS works as a SPA (here you can read a bit about it). The point is that when the page reloads, as any other SPA, it will lose all its data and the app will be "reeboted". This is why you are getting this problem.

There's an easy way to solve it: When the app loads/reloads, it goes to the app.config() and rigth after that it goes to the app.run() (if any). So my solution for you is to keep your user's info data on the localstorage (works like a cookie) and then ask for it from there when the app initialize.

angular.module('MyApp').run(function($rootScope){
    if(!angular.isDefined($rootScope.userInfo) && localstorage.userInfo){
        // UserInfo exists in localstorate but not on $rootScope. This means the page was reloaded or the user is returning.
        $rootScope.userInfo = localstorage.userInfo;
    }else if(!angular.isDefined($rootScope.userInfo) && !localstorage.userInfo){
        // User is not logged at all. Send him back to login page
    }else if(angular.isDefined($rootScope.userInfo)){
        // User is logged in. You can run some extra validations in here.
    }
});

I'm assuming you keep your users info on a variable $rootScope.userInfo

That been said, I strongly recommend you try a Service to keep your data rather than on the $rootScope. Here's a guide on how you can achieve that.

I hope this solves your issue.

**UPDATE

If you're working with Ionic you can try something like this:

var myApp = angular.module('myApp', ['ionic']);
    myApp.run(function($ionicPlatform) {
        $ionicPlatform.ready(function() {
        //load your settings from localStorage or DB where you saved.
    });
});

Took it from this reference.