Home » Angularjs » angularjs Ionic and global variables: best practice to make a variable available globally

angularjs Ionic and global variables: best practice to make a variable available globally

Posted by: admin January 30, 2018 Leave a comment

Questions:

I am new to Angular/Ionic.
Before using Angular/Ionic, at the launch of my app, I was checking if we were under Phonegap or a browser using and storing this information in a global boolean variable and then checking if the app was online or offline and storing it to a global variable too, like this :

var isPhoneGap;
var connectionStatus;
isPhoneGap = checkIfPhoneGap();

//later in the code :

connectionStatus = checkIfOnline();

function checkIfPhoneGap() {
    var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1; // && document.URL.indexOf( 'file://' );
    if ( app ) {
        return true;
    } else {
        return false;
    }
}
function checkIfOnline() {  
    if ( isPhoneGap ) {
        if (checkConnection() == "none" ) {
            connectionStatus = 'offline'; 
        } else {
            connectionStatus = 'online';
        }
        function checkConnection() {
            var networkState = navigator.network.connection.type;
            var states = {};
            states[Connection.UNKNOWN]  = 'Unknown connection';
            states[Connection.ETHERNET] = 'Ethernet connection';
            states[Connection.WIFI]     = 'WiFi connection';
            states[Connection.CELL_2G]  = 'Cell 2G connection';
            states[Connection.CELL_3G]  = 'Cell 3G connection';
            states[Connection.CELL_4G]  = 'Cell 4G connection';
            states[Connection.NONE]     = 'No network connection';
            //console.log('Connection : ' + Connection);
            //console.log('Connection type: ' + states[networkState]);
            return networkState;
        }
    } else {
        connectionStatus = navigator.onLine ? 'online' : 'offline';
    }
    return connectionStatus;
}

Now I would like to do the same with Angular/Ionic, I understand that I have to use a “Service”. But is it the best way to make this information available through all the code ?

I am doing the following, but is it the “best practice” ?

in index.html :

<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>

in services.js :

angular.module('SnowBoard.services', [])

.factory('isPhoneGap', function() {

    var appp = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1; // && document.URL.indexOf( 'file://' );
    if ( appp ) {
        return true;
    } else {
        return false;
    }

})

;

in app.js :

angular.module('SnowBoard', ['ionic', 'SnowBoard.controllers', 'SnowBoard.services'])

.run(["isPhoneGap","$ionicPlatform", function(isPhoneGap, $ionicPlatform) {
  $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);
    }
    if(window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
  });

  //CHECK IF ONLINE
  connectionStatus = checkIfOnline(isPhoneGap);

  //DEBUG
  //var debugOptionUseLocalDB=0;
  //updateProDB(connectionStatus, debugOptionUseLocalDB);
}])
.config(function($stateProvider, $urlRouterProvider) {
//...all state configurations
})
.config(function($stateProvider, $urlRouterProvider) {
//...
});

This works for now, but I need the boolean isPhoneGap to be available everywhere I need it (almost everywhere in my app).

Can you converge to the best practice to do this ?

Thanks

Answers:

You should not set variables using $rootScope, and try to refrain from using $scope as much as possible. Using LocalStorage is okay, but this data will persist. I would recommend setting up a factory to store and retrieve variables using SessionStorage. SessionStorage is tied to the tab you have open, so the data is gone when it is closed.

This is one of my session storage services. I throw $cookieStorage in case local storage isn’t available. Also, localStorage can only store strings. This is why you will see me converting objects and arrays to and from JSON as needed. After injecting sessionService, I need only call sessionService.store(name, data) to store a session variable or sessionService.persist(name, data) to store persistent data i.e. userName if “Remember Me” is checked. :

.service('sessionService', ['$cookieStore', function ($cookieStore) {
    var localStoreAvailable = typeof (Storage) !== "undefined";
    this.store = function (name, details) {
        if (localStoreAvailable) {
            if (angular.isUndefined(details)) {
                details = null;
            } else if (angular.isObject(details) || angular.isArray(details) || angular.isNumber(+details || details)) {
                details = angular.toJson(details);
            };
            sessionStorage.setItem(name, details);
        } else {
            $cookieStore.put(name, details);
        };
    };

    this.persist = function(name, details) {
        if (localStoreAvailable) {
            if (angular.isUndefined(details)) {
                details = null;
            } else if (angular.isObject(details) || angular.isArray(details) || angular.isNumber(+details || details)) {
                details = angular.toJson(details);
            };
            localStorage.setItem(name, details);
        } else {
            $cookieStore.put(name, details);
        }
    };

    this.get = function (name) {
        if (localStoreAvailable) {
            return getItem(name);
        } else {
            return $cookieStore.get(name);
        }
    };

    this.destroy = function (name) {
        if (localStoreAvailable) {
            localStorage.removeItem(name);
            sessionStorage.removeItem(name);
        } else {
            $cookieStore.remove(name);
        };
    };

    var getItem = function (name) {
        var data;
        var localData = localStorage.getItem(name);
        var sessionData = sessionStorage.getItem(name);

        if (sessionData) {
            data = sessionData;
        } else if (localData) {
            data = localData;
        } else {
            return null;
        }

        if (data === '[object Object]') { return null; };
        if (!data.length || data === 'null') { return null; };

        if (data.charAt(0) === "{" || data.charAt(0) === "[" || angular.isNumber(data)) {
            return angular.fromJson(data);
        };

        return data;
    };

    return this;
}])

$cookieStore is part of ngCookies. Make sure you have angular-cookies.js included and load ngCookies as you would any module. Angular ngCookies

Questions:
Answers:

First off, Im pretty new to both ionic and angular, however I had the same problem with my web app angular and I have done following to get it working

1 ) assign variables to $rootScope, that way its visible to all the controllers

2 ) assign variables to $scope , which is visible by current context
Ex: controller and the html pages uses that controller

3 ) localStorageService , coz this will hold the values even after user refreshes the page.

again please note, this is what I did in my angular web app and might not be the best practices, but I hope u get the idea

Questions:
Answers:

There are methods available in ionic.Platform that assist in getting back the data you need in regards to the device type.

http://ionicframework.com/docs/api/utility/ionic.Platform/

You could alternatively look at adding ngCordova, which has a bunch of useful wrappers around cordova plugins, including the device plugin.

http://ngcordova.com/docs/#Device