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
Related
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.
I'm using the yeoman meanjs generator and am a bit confused. In my core Angular controller I have this setup:
angular.module('core').controller('HeaderController', ['$scope', 'Authentication', 'Menus',
function($scope, Authentication, Menus) {
$scope.authentication = Authentication;
$scope.isCollapsed = false;
$scope.menu = Menus.getMenu('topbar');
$scope.toggleCollapsibleMenu = function() {
$scope.isCollapsed = !$scope.isCollapsed;
};
// Collapsing the menu after navigation
$scope.$on('$stateChangeSuccess', function() {
$scope.isCollapsed = false;
});
}
]);
How does the Authentication object come into scope here? Where is created ?
For example if I wanted to add an object say foobar which was from my MongoDb what's the standard practice of getting this data into the angular controller from the server size?
David
Authentication is a service defined in the services folder which sits alongside to the controller folder you are in. Here is the service definition:
angular.module('users').factory('Authentication', [
function() {
var _this = this;
_this._data = {
user: window.user
};
return _this._data;
}
]);
What you see here is the standard way of referencing services in your controllers. In angular, you typically have services that have business layer logic including logic to talk to the backend over restful protocols.
To reference it, you simply give the name of the service in the controller definition and that service reference is made using dependency injection. There is an injector that runs behind the scene to find the service by that name, and create a reference to it.
So any other service that you create, create just like this Authentication service and then just put the name of the service in the controller definition in a similar fashion to use the service.
Now something referencing the MongoDb database does not make sense here as this is the front end portion of the stack. This code executes on the client browser and not the server.
The MongoDb database sits on the server and all the code that you see in the app folder in this stack is the server side code. All the code in the public folder is the front end code. Hope this helps.
I have not used this particular generator (I use angular-fullstack-gennerator). But it is likely similar.
Yours seems you need to use a CRUD sub generator. That will give you the ability to crate, read, update and delete. So what ever you call it you will then import this into the controller you need it in.
If you called it CRUDserverstuff, you could then import it like the line below:
angular.module('core').controller('HeaderController', ['$scope', 'Authentication', CRUDserverstuff, 'Menus',
function($scope, Authentication, CRUDserverstuff, Menus) {
//use it as you would any other objecte here
CRUDserverstuff.post(myData);
}
I am new to angular as well so one thing I am not sure of is if it needs to be or even should be put twice like that on the import lines. That confuses me a bit.
If you are not tied to using the MEAN stack generator I found the fullstack one very friendly to a beginner. The one thing to be careful to learn is the file structure. Full disclosure: I an NEW to angular and the MEAN stack. This is also my first answer ever on here so there you go.
I have a AngularJS app, that depends on a webservice, I would like to load some more controllers into the app from a remote host, after the app is loaded. I don't know i this is possible?
In my controller, I want to load some more controllers (js files)
.controller('FrontpageCtrl', function($scope, $stateParams, $filter, $sce, contentService) {
console.log("hitting FrontpageCtrl ... ");
contentService.promise.then(function(data){
var page = $filter('filter')(data, {id:$stateParams.pageId})[0];
$scope.content = $sce.trustAsHtml(page.content);
// Load a controller, directive and other provided by the webservice!
$scope. ...
});
})
Currently angular does not provide a way to load modules dynamically. Hence, any angular built in object (directives, controllers, factories, etc.). This means your controllers (from the web service) should be loaded on bootsrapping angular (probably as a resource on the index page).
There are some ways to dynamically load stuff after bootstrapping, here are a few:
My personal favorite: https://github.com/ocombe/ocLazyLoad.
Closest to your question: http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs
https://www.startersquad.com/blog/angularjs-requirejs/
There are many more stuff to be found.. you can obviously google it.
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!
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');
}
]);