How to make global variables in angularJS

All we need is an easy explanation of the problem, so here it is.

i have this problem where when you register you get to the Users page. And its suppose to say “Welcome ” The username dosent show up for On The Webpage for reason im not to sure about… please help here is the plunkr:

http://plnkr.co/edit/qB3Gkeq5ji1YQyy0kpGH?p=preview

Please i need help..

i need to get some code for plunker so :
script.js:

var app = angular.module('LoginApp', ["firebase", "ngRoute"])

app.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'registration.html',
        controller: 'AuthCtrl'
      })
      .when('/logIn', {
        templateUrl: 'login.html',
        controller: 'AuthCtrl'
      })

      .when('/User', {
        templateUrl: "User.html",
        controller: 'AuthCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });


  });


app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var ref = new Firebase("https://uniquecoders.firebaseio.com/");
    return $firebaseAuth(ref);
  }
]);


app.controller("AuthCtrl", ["$scope", "Auth",
  function($scope, Auth) {


      $scope.createUser = function() {

        $scope.message = null;
        $scope.error = null;
    var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
  ref2.createUser({
    email: $scope.email,
    password: $scope.password
  }, function(error, userData) {
    if (error) {
      switch (error.code) {
        case "EMAIL_TAKEN":
          alert("The new user account cannot be created because the email is already in use. Try to login");
          break;
        case "INVALID_EMAIL":
          alert("The specified email is not a valid email.");
          break;
        case "INVALID_PASSWORD":
          alert("The Specified Passowrd Is not valid.")
          break;
        default:
          alert("Error creating user:", error);
      }
    } else {
      alert("Successfully created user account with uid:", userData.uid);
      alert($scope.UserName)

      window.location.hash = "/User"
       $scope.usernames = "HEY"
    }
  });


      };

       $scope.logIn = function(){
        $scope.message = null;
        $scope.error = null;

        ref2.authWithPassword({
          "email" : $scope.logInemail,
          "password" : $scope.logInemailpassword

        }, function(error, userData){

          if(error){
            alert("Login Failed.")
            console.log(error)
          }
          else{
            alert("Logged In!")
          }

        })

      }

  /*  $scope.removeUser = function() {
      $scope.message = null;
      $scope.error = null;

      Auth.$removeUser({
        email: $scope.email,
        password: $scope.password
      }).then(function() {
        $scope.message = "User removed";
      }).catch(function(error) {
        $scope.error = error;
      });
    };*/
  }
]);

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

When your app changes routes, it destroys the scope of the old controller and creates a new scope. This happens even if you use the same controller for both the old and new route.

Store persistent data in your Auth factory along with the functions that create that data.

app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var AuthObj = {};
    //Store persistent data on AuthObj
    AuthObj.ref = new Firebase("https://uniquecoders.firebaseio.com/");
    AuthObj.createUser = function(email,password) {
        AuthObj.ref.createUser(
            {email: email, password: password },
            function(error, userData) {
                if (error) {
                    //process error
                } else {
                    //store data on AuthObj
                    AuthObj.userData = userData;
                }
             }
        );
        return AuthObj.userData;
    };
    //return AuthObj which holds functions and data
    return AuthObj;
  }
]);

Use your controller to invoke those functions and retrieve persistent data.

app.controller("AuthCtrl", ["$scope", "Auth",
  function($scope, Auth) {
     //retrieve userData
     $scope.userData = Auth.userData;
     $scope.createUser = function() {
          if ($scope.userData) {
              return;
          } else {
              $scope.userData =
                   //invoke function in factory
                   Auth.createUser($scope.email,$scope.password);
          };
     };
   }
]);

This way the data remain and persist when you change routes.

Method 2

There are many things in your code that you might want to take care of, but some quick and partially dirty solutions:

Do not include all of your javascript files on your nested templates. Anything that is routed to in your ng-view should just be the html you want to be inserted within that <div>. No CSS links, no script tags, nothing but HTML that would normally be within the body of a page.

On your registration page, your username ng-model needs to match what you are passing as an argument to your ng-click. So instead of ng-model="userName" you need it to be ng-model="username" to match ng-click="createUser(username, email, password)".

Your other major issue is that $scope is being overwritten each time you change views because each one of your routes has the same controller. So conceptually, you may be thinking that the username (which you have stored as the plural $scope.usernames for some reason) is there for you to access still on $scope. But that is not the case, as each view is running on its own unique instance of the Auth Controller. The quickest solution since you don’t know how to implement services is probably to inject $rootScope into your controller, and then put usernames on $rootScope instead of $scope (though keep in mind using $rootScope in production is considered bad practice), as $rootScope will persist across all of your controllers. So your javascript file would look more like this:

app.controller("AuthCtrl", ["$scope", "$rootScope", "Auth",
function($scope, $rootScope, Auth) {

and then

$scope.createUser = function(username, email, password) {
$rootScope.usernames = username
$scope.message = null;
$scope.error = null;

Method 3

When you navigate to the User view angular creates new instance of AuthCtrl controller, which mean new scope, that’s why there are no value there.

Use services to share data (or even scope) between controllers.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply