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

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.

Related

Is there any way to share one object between two web pages in AngularJs without using $cookies

In AngularJs is there any way to share object between two web pages without using $cookies. For example my Login page controller have different angular.module and my other controller have different angular.module but I need to share credentials between Login page and another page without using $cookies.
Between independent page
You can use the standard HTML5 sessionStorage and localStorage object
For simple synchronous storage access HTML 5 introduces the localStorage attribute on the Window object:
localStorage["status"] = "Idling.";
LocalStorage is like cookie, sessionStorage will be clean when closing your browser.
In angular
You can use a factory which is technically a singleton. But if you refresh your page, all JS will be re-initialize and you will lose your data. A Service is also possible.
Here is a link on an other topic explaining difference between Services and Factory : AngularJS: Service vs provider vs factory
To create Services/Factory, give a look at Angular official documentation, it is well explained.
Perfect mix
What you need to do is create a Service, and at each modification you stringify it to store on a local/session Storage. On load, when angular create your service, you look in your storage for initialization value and your object is back.
This is quite common for authentification for exemple. You store a token to keep authentification when refreshing ;). Let me know if any difficulty to implement.
Have you considered creating a Service which stores these login credentials? You could then use Dependency Injection to have this Service available in both controllers.
Sharing the information between different pages is a critical task which can be done with the help of Controllers.
In AngularJS, we can share the data between controllers in three ways:
Factory: Object is created inside the factory and return it .
Service: With the service, you just have a standard function that uses the this keyword to define function.
Provider: With the provider, there’s a $get you define and it can be used to get the object that returns the data.

ANGULAR runtime add service to module

How can i add a service to the module/angular app at runtime.
Will $injector or $provide help me?
Something like
app.addService('s',['k',function(k){console.log('new Service k');}]);
Yes, $provide will do it. See the documentation at https://docs.angularjs.org/api/auto/service/$provide
So you could do something like this (from within foo):
app.factory('foo',functon() {
$provide.factory('s',function() {
console.log("new service 's'");
});
});
The problem is that you cannot inject $provide directly into the service, so you need to capture it at module creation time.
The question is, why would you want to do this? Since the service 's' isn't declared until 'foo' is run, you run the risk of calling the service as a dependency at some other point. If it is anywhere within a normal injection, you would probably get some weird error.
Matter of fact, I think the only way it would work is by using the $injector to get it from within some other service.
So, yes, you could do it, but would you really want to?
Look at this fiddle: http://jsfiddle.net/ch8vu4ng/1/

Can AngularJS inject named instances of factories or services?

I am just starting with Angular with a project that seems really suited to it. In this project i must make several instances of a form builder so i have decided to make a service out of the form builder code. All is fine and good up until i take in account the other requirement: Form previews.
I was thinking of something along the lines of what this guy does but then i realised using his approach implies i cannot store/share more than one form (At least with the default injection approach used by Angular) so i gave it some thought and decided that having one instance of the FormBuilder service for each form would cut it. How can i control which instance of my service is injected into my controllers?
Propably you would not inject a specifc FormBuilder instance rather than a InstanceRegistry?
Create a service which returns a function taking the name to resolve and returns the resolved instance. This will be called from your controller.
Optionally, you could create resolves for the route if you are using either ngRoute or ui.router and do the resolving in the resolve block.
.when("...",{
controller:"...",
templateUrl:"...",
resolve:{
form1:["$formFactory", function($formFactory){
return $formFactory("form1")
})
}
})
HTH

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!

Is it possible to create an AngularJS service without a module?

In AngularJS there is a short form to create controllers, so you do not have to use a module for this. This short form is to simply define a function
function FooController ($scope) {
// ...
}
and reference it from the HTML markup using ng-controller:
<div ng-controller="FooController">
...
</div>
Now, my question is, whether there is a similar "short form" to define services? In other words: Can you define (and use) a service without using a module?
Please note that I know that it perfectly makes sense to structure your applications using modules, and not doing so could / should be regarded as bad practice. It's just that I am explaining AngularJS to someone who's completely new to it, and the question arose today. So it's just for curiosity and completeness.
Quoted from the doc of Creating Services
To register a service, you must have a module that this service will
be part of.
So I guess the answer is no.
Since the ng module is always loaded, you could define your service on the ng module:
angular.module('ng')
.service('aService', function () {
// you really shouldn't do this
});
It works, but you shouldn't be messing with a module that you don't own.
If you're trying to explain to someone why using your own modules with .controller is good:
Talk to them about testing. It's a lot easier to mock things if you're using modules
If you need to have other modules as dependencies (like angular-ui)
If you want to decorate another service (e.g. $http)
If you need to register directives, filters, animations, etc.
It's a lot nicer to have modular code :)
It's an angular concept I don't understand at all, I always believed "separation" is good, so I dont get why we need to associate a service to a specified application.
Here what I am doing: you can declare your angularjs application as a global object:
window.markrApplication = angular.module('markrOptionsApp', ....)
And declare all your services like this:
markrApplication.service('data', ....
Of course you need to have all the dependencies set on all your angularjs application.

Resources