angularjs Ionic and global variables: best practice to make a variable available globally
angularjs, ionic-framework
Solution
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
Problem
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