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
Using global variables causes very tight coupling of code. Using global variables causes namespace pollution. This may lead to unnecessarily reassigning a global value. Testing in programs using global variables can be a huge pain as it is difficult to decouple them when testing.
The value of a global variable can be changed accidently as it can be used by any function in the program. If we use a large number of global variables, then there is a high chance of error generation in the program.
So, by using a local variable you decrease the dependencies between your components, i.e. you decrease the complexity of your code. You should only use global variable when you really need to share data, but each variable should always be visible in the smallest scope possible.
Avoid global variables or minimize the usage of global variables in JavaScript. This is because global variables are easily overwritten by other scripts. Global Variables are not bad and not even a security concern, but it shouldn't overwrite values of another variable.
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
First off, I'm 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
assign variables to $rootScope
, that way it's visible to all the controllers
assign variables to $scope
, which is visible by current context. Ex: controller and the html pages uses that controller
localStorageService, because 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 you get the idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With