what is the diffrence between factory and controller? - angularjs

I am developing an AngularJs app . when I search about some controller samples like firebase Auth
.factory("Auth", function($firebaseAuth) {
var usersRef = new Firebase("https//<YOUR-FIREBASE-APP>.firebaseio.com/users");
return $firebaseAuth(usersRef);
})
this will use factory instead of controller.
I have changed it to controller and it works as well.
I need to know about the difference.

A factory is used is here because you could use the same Firebase Auth for multiple controllers.
Instead, if you are hardcoding this into a specific controller, you would have to do the same for each and every other controllers which need the Auth.(which is bad).
Also, it is the cliche that a new feature is added as a Service or Factory.

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.

How do you connect server side properties into angular controller

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.

How do you inject dependencies into services in angular.js?

I'm using AngularFire to create a web app. Several of my controllers use a lot of the same functions to access the data in Firebase, so I am trying to write a service so that I don't have to rewrite the same functions for every controller. The problem is that I can't seem to get the Firebase dependency into the service. I'm using the following code:
angular.module("myApp", ["firebase","ngDraggable"])
.factory("GetData",['$firebase','FirebaseConn',function($firebase,FirebaseConn){
$firebase(new Firebase("https://XXXX.firebaseio.com/")).$asObject().$bindTo(scope, "firebaseData");
return {
};
}]);
But when I try to run this, I get the following error:
Unknown provider: FirebaseConnProvider <- FirebaseConn
I am able to access Firebase through my controllers, so it's not a problem connecting to firebase.js or angularfire.js.
How should I inject Firebase into my service so I can access the data in all of my controllers? Or, is there a better way to go about this? I'm rather new to Angular so if there's a better way to share functions between my controllers I'm all ears.
You inject them precisely the same way that you do in Controllers and Directives.
This is a common error in AngularJS, and it means you're injecting something that isn't injectable. It almost always means either you missed a dependency (probably not in this case) or that you're asking for something that doesn't exist in the first place.
This is almost certainly your problem. You're asking for firebase and getting it, but it can't find FirebaseConn. What is that, some variable of yours that you're using to track your connection? Because you aren't using it, and the AngularFire docs I just looked at don't, either.
Consider something more like the following:
angular
.module("myApp", ["firebase", "ngDraggable"])
.service("firebaseManager",['$firebase', function($firebase) {
var ref = new Firebase("https://XXXX.firebaseio.com/"),
sync = $firebase(ref);
this.getData = function() {
return sync.$asObject();
};
});
Obviously, customize this to suit. Two comments:
You probably do want a service instead of a factory. This is a common point of confusion when you first start using AngularJS. You only need a factory if you plan to get involved in the instantiation of the service in some way. A service is just a shortcut form of a factory with the most common usage - the one you probably want.
You will now inject this service firebaseManager into your controllers. When you do, they will be able to call firebaseManager.getData() and any other methods you define. firebaseManager will be a singleton, so all of this will go through one common Firebase connection.

Using reusable models and injecting these where required in Angular

Anyone know the best recommended way of creating models in a separate JavaScript file and have these injected into the controllers that need them, rather than creating the models on fly normally in the controller?
This would make it so much easier to pass around the model and you would know exactly what you was passing around.
I have some thoughts on using Services, and inject these where I need i.e. controllers.
Controllers would then pass these onto specific services to do any heavy lifting to keep my controllers nice and light.
Is services the only and recommended way to go ? Or is there a better alternative way ?
Any use of third-party libraries / modules would also be considered.
I think services are the way to go. Not only are they injectable but they are also Singletons - meaning wherever they are injected, the same instance is shared.
Example of a service which uses the $http service to make an asynchronous call to retrieve data:
app.factory('customerService', function($http) {
var customers = [];
$http({ url: 'api/customers/all', method:'GET'}).success(function(data) {
angular.copy(data, customers);
});
return {
customers: customers
};
});
In your controller or directive, you can then inject the service and bind customers to your scope:
app.controller('ctrl', function($scope, customerService) {
$scope.customers = customerService.customers;
});
The best way to do it is by service for couple of reasons.
If you use ng-view and routing the service is not reloading and your data is safe in service
It's easy injectable to controllers
Provides two-way data binding between controllers
working plunker with two-way data binding between controllers
http://plnkr.co/edit/pt2xwlYqvY3r840tHJ92?p=preview
NOTE: if you don't have a dot in your model you are doing something wrong ;)
I believe services are the best way for this.
I have used scope inheritance to place some methods that most of my app would need at once such as a routing method I attached these to the .run () method of my main module/app.
You could separate your models into separate modules if you needed to structure your app that way.

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