Storing Data in AngularJS on Mobile Devices - mobile

I'm currently working on a Mobile WebApp built with AngularJS. The basic functionality is similar to a simple ToDo's app: Create a list of items (with ng-repeat) and mark those items as checked or delete them from the list. Checked items are being pushed into a seperate ng-repeat controller.
My current problem is: If you reload the page or close the app, the list contents are gone. I have to be able to store the data of my ng-repeat controllers to localStorage, IndexedDB, WebSQL, Cookies or whatever solution is the most elegant on mobile devices.
I know there are several solutions out there: There's the $cookies / $cookieStore module of the Angular API, there's a solution based on prestistence.js and so on. But I couldn't figure out wich solution is the best for mobile, cross device. I don't want to restrict the app to certain plattform, though I'm primary aiming at Firefox OS atm.
Thanks for any form of advice!

I recommend localStorage. The API is simple and widely supported.

If you'd like to store your data in the cloud I recommend using Firebase in conjunction with Angularfire. It will get you up and running in a matter of minutes.
First you include Firebase and AngularFire:
<script src="https://cdn.firebase.com/v0/firebase.js"></script>
<script src="angularFire.js" type="text/javascript"></script>
Then you declare firebase as a dependency for your angular app:
var myapp = angular.module('myapp', ['firebase']);
Now all you need to do is bind a Firebase URL to a model in your controller:
myapp.controller('MyCtrl', ['$scope', 'angularFire',
function MyCtrl($scope, angularFire) {
var url = 'https://MyFirebaseURL.firebaseio.com/foo';
$scope.foo = angularFire(url, $scope, 'foo');
}
]);

Related

When to use multiple controllers Angularjs

I'm a bit new to Angularjs. I'm confused about multiple controllers. I know Angular app can have multiple controllers. But I'm confused when to use multiple controllers. What's the advantage of having multiple controllers? Can anyone help me to clarify this? Thanks
In order to modularize your application based on the feature wise, you can have multiple controllers.
For example if you have a login feature, you can have a separate controller which does the login part(Fetching data,checking the authentication etc)
var app = angular.module('app', []);
app.controller('LoginController', function ($scope) {
//Controller Code Here which fetches the API and check authentication
});
app.controller('ProductController', function ($scope) {
//Controller Code Here which loads the products
});
For different functions we need different controllers. For example if you need a ui modal to display something then for that modal you need different controller which will handle only modal's functionality. If you try to code everything in single controller then it will be confusing for you when in future you want to edit some contents of any html page.

Combining AngularJS with another SPA framework - compiling injected HTML

I have an old single page app and for some new pages within the app I would like to use Angular, without changing how navigation and the app in general works already.
I would like to instantiate the angular app just once since it is running within a SPA already. I can do that either using ng-app attribute or programmatically using angular.bootstrap method.
But then when user navigates to a new page and the old app loads the HTML and inject it to DOM, I want the new page to be processes by Angular. I understand the new HTML must be compiled by Angular. Is there an efficient way to do it? The HTML is already in DOM, I don't want to remove it, compile it and inject it again. Is there an efficient way of doing it?
The new page's HTML can look like this for example:
<div ng-controller="TestController">
<h1>{{title}}</h1>
</div>
The controller is created in app.js and loaded in index.html. It' simple for the test and looks like that:
angular.module('app', [])
.controller('TestController', ['$scope', function ($scope) {
$scope.title = 'some title';
}]);
Alternatively for each page I can instantiate the app using already mentioned angular.bootstrap, which does the trick, but that doesn't feel right.
What I ended up doing is:
1) in the main (app) module getting reference to $compile and $rootScope in app.run and storing the reference outside Angular
2) in the old app navigation, after navigation to a new page happens calling:
$compile(pageRoot.contents())($rootScope);

Ionic/Angular and Socket.IO - Show popup upon Socket.IO event received

I'm trying to build a real-time mobile application utilizing the Ionic Framework (AngularJS) and Socket.IO.
Coming from a jQuery background, I'm kind of new to the whole Ionic/Angular application design and structure (e.g., controllers, services, etc.). So I was wondering, how should my application be structured, or what is the best/ideal way of structuring my application?
More specifically, in an Ionic/Angular-structured application, where should my usual Socket.IO code go? I've seen one component (https://github.com/btford/angular-socket-io) which (as I understand) encapsulates Socket.IO code within an Angular factory. Is this the way to go?
What I really want to achieve are the following:
Open an (Ionic) popup when a Socket.IO event is received and
emit/send a Socket.IO event/message upon a UI event (e.g., button click).
How should my Ionic/Angular code structure look like to achieve this? That is, which code goes into which component/controller/service/factory?
Even a high-level description of the structure would do as a starting point.
As an example for you, Here's how I did it with a ChatCtrl controller.
<!-- app.js -->
<script>
angular.module('chatApp', ['ngAnimate'])
.controller('ChatCtrl', ['$scope', '$http', function($scope, $http) {
var socket = io.connect();
// on connect, grab username
socket.on('connect', function(data) {
nickname = prompt("What's your name?");
socket.emit('join', nickname);
});
socket.on('statusConnected', function(data) {
$scope.status = data;
$scope.$apply($scope.status);
});
}]);
</script>
My popup is a JavaScript nickname = prompt("What's your name?") but you could probably trigger a modal or whatever other popup you want with some more JS

Module injections vs Single application

I have been working with AngularJs for a while and I now feel comfortable enough with it that I started to review my earlier work.
So I started out with following the basic tutorials and got used to setting up the application, controllers and services as following:
Module injections
// application.js
angular.module('appname',
[ // dependencies
'ui.router'
, 'someController'
]);
// somecontroller.js
angular.module('someController', [])
.controller('someCtrl',
['$scope', function ($scope) {
// Some stuff
}]);
And of course including js files in my index.html e.g.:
<script src="path/angular.js"></script>
<script src="path/angular-ui-router.min.js"></script>
<script src="path/application.js"></script>
<script src="path/somecontroller.js"></script>
Since I tend to separate all logic by feature (separate directory, own MV* structure per directory), I found that the list of dependencies can grow rather large. And also I think adding each controller, service etc. to the app dependencies is kind of a drag.
So I started to do it this way instead:
Single application
// application.js
var app = angular.module('appname',
[ // dependencies
'ui.router'
]);
// somecontroller.js
app.controller('someCtrl',
['$scope', function ($scope) {
// Some stuff
}]);
The obvious win for doing it like this is that I do not longer have to add the controller reference to the app dependencies.
So now my question(s) are:
Besides the obvious, what is the difference between the 2 methods?
From the Angular perspective which of the methods is considered
"good/bad practice"? And why?
I don't think the second method is good. You add all controllers to your app main's module. If you want to truly group your code by feature, I recommend a third approach :
// application.js
angular.module('appname',
[ 'ui.router'
, 'appname.booking'
]);
//booking.mod.js
angular.module('appname.booking', []);
//booking.ctrl.js
angular.module('appname.booking')
.controller('BookingCtrl', function ($scope) {
// Some booking logic
}]);
This way, you create a module per feature and obtain a project architecture easy to understand and navigate.
Looks like you need to read a bit more about modules.
The difference between your two approaches is that in the first one you create a different module for your controller and by injecting that module into the app dependencies you tell angular "by the way, I want the features that come with that module, too".
In your second approach, you only have a single huge module for the entire application, which means all the controllers, service, directives, .. will be automatically considered as part of the application.
Both approaches work, however having different modules for different functionality could help you structure you application better, as well as provide more reusability & easier testing.
In your first method you are creating different modules for your controller. That's why you have to inject your controller name at the time of creating Angular JS app.
angular.module('appName', ['controllerName']);
angular.module('controllerName', []);
In the second approach you are only creating a single app and you are attaching the controller to this app. In this case you don't have to inject the controller name at the time of creating the Angular JS app.
var app = angular.module('appName', []);
app.controller('controllerName', function(){});
About your second question, it depends on the type of application you are developing. For a small single page application a single app module will do fine
When working on large applications everything might not be contained on a single page, and by having features contained within modules it's much simpler to reuse modules across apps. So in this case your first approach is better.
You can create different modules like shown below and can inject to your app;
var sharedServicesModule = angular.module('sharedServices',[]);
sharedServices.service('NetworkService', function($http){});
var loginModule = angular.module('login',['sharedServices']);
loginModule.service('loginService', function(NetworkService){});
loginModule.controller('loginCtrl', function($scope, loginService){});
var app = angular.module('app', ['sharedServices', 'login']);

The best way to Mock Services in AngularJS to decouple REST calls

I am building a web application with AngularJS and have built out a AngularJS Service that my controller uses to create, retrieve, update, delete data from. I want to farm out the UI work to another developer, but I don't want them to require the dependencies that the AngularJS Service does. I'd like to build a Mock Service and just return mock data rather than call the live REST service.
My App is set up like this:
var myApp = angular.module('myApp', ['ui.bootstrap']);
My Controller currently hooks up to the Service using:
myApp.controller('TodoCtrl', function TodoCtrl($scope, $JSOMService) {
$JSOMService.DoStuff();
});
And my Service is defined like this
myApp.service('$JSOMService', function ($q, $http) { ... });
What the are best ways to handle switching out the service for another one? This is a little different from Unit Testing and I wondered if there are any common ways of doing this?
For now I'm just having a slightly different code base where I just switch out the Angularjs Service javascript files loaded to handle this.
You can get access directly to the provider service, which controls injections. It would look something like this, where $provide is injected:
$provide.value('$JSOMService', MockJSOMService());
This will basically say, whenever someone asks for $JSOMService, give them whatever was returned from MockJSOMService.
You can set this up at the when you set up your app. Like this:
myApp.run(['$provide', function($provide) {
$provide.value('$JSOMService', MockJSOMService());
}]);
This is basically how you could switch out services. Admittedly a little funky, but I hope this helps!

Resources