I'm using AngularJS and Restangular. How can I define the baseUrl to use on run time? I dont think that I can use run or config methods since is the user the one who selects the server to connect to.
I have this so far:
var rest = Restangular.withConfig(function(RestangularConfigurer){
RestangularConfigurer.setBaseUrl(baseUrl);
});
This works fine when using rest to do the calls BUT when Im in need of using Restangular.copy this Restangular does not have the baseUrl defined.
How could I defined the Restangular.baseUrl for the Global/ Singleton one on run time?
The docs say:
You can set all these configurations in RestangularProvider or
Restangular service to change the global configuration [...]
This means, you are able to inject Restangular into your controller, directive, service, ... , and call Restangular.setBaseUrl(baseUrl). I can assure that this works with other configuration methods like setDefaultHttpFields too.
Related
I had a use-case where I wanted to make the session timeout of the application configurable by making a call to REST api and get the value using $http. But as I found in this link how to inject dependency into module.config(configFn) in angular that services cannot be injected in config method, I have found this solution to make this work in the config:
var $http = angular.injector(['ng']).get('$http');
This is working fine, what is the difference between the two approaches and why this is working ? Also is there any limitation of using this approach.
angular.injector creates a new injector (application instance). It is misused most times and rarely ever needed in production.
It will have its own $http, $rootScope, $q, etc instances:
angular.injector(['ng']).get('$http') !== angular.injector(['ng']).get('$http');
The use of angular.injector in config block is an antipattern. It will result in untestable and potentially buggy code. $http request is asynchronous, application initialization will be completed first and likely result in race condition.
Most times when a need for $http in config appears, it should be performed in route resolver. If the response contains information that should be used to configure service providers and should be available in config block, it should be fetched prior to application bootstrap - in fact, there should be two applications, as shown here.
I only see .config with passing $routeProvider, what else will passing through by .config and also want to know what are the parameters will pass through by .run in angularjs
These are dependency injected services.
So for config you should be asking for constant or provider. For run you should be asking for service, factory, value, constant.
You should notice i'm saying should be asking for, because we're dependency injecting the services, the function parameters are effectively asking angular DI for particular instances. If angular has one it will supply the function arg with that instance, similar to a fn.call({}, someDep)
So for example:
angular.module('myMod', [])
.provider('myFactory', myFactoryProvider)
.factory('anotherService', anotherServiceFactory)
.config(function (myFactoryProvider) {
})
.run(function (myFactory, anotherService) {
/** myFactory is the service that was setup
* by the config myFactoryProvider
*/
});
I've left out the implementations for myFactoryProvider and anotherServiceFactory so you look up angular docs to see what they're about.
The config and run describe the phases of an angular application. config phase is for setting up services and pipelines like the $http request pipeline and generally pre-app configuration.
The run phase is for when the app has loaded and you want to do something like load some user information from the api or anything else post-app load.
I personally used to use the config all the time with $stateProvider and things. But, I rarely used the run function.
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.
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
I am trying to resolve a service programmatically in angular js from a particular module, but I can't find the correct way to do that.
I know using angular.injector(['NameOfModule']).get('NameOfService') I can retrieve the service. However, using angular.injector does not retrieve the injector of the given module and instead creates a new injector. This means that when it retrieves the service, as it is a new injector, it does not have the service cached and so creates a new one. This means that I will have several of the same service, and so it will no longer be a singleton, which will obviously cause problems.
What I essentially want to do is retrieve the injector from a particular module so I can try to retrieve the (cached or not cached) service from that injector. Does anyone know how to achieve this?
What i would suggest would be to inject the $injector service into the controller\service where you want to use it. This would return the injector that the app is using and not create a new injector as angular.injector does. See detailed explanation in this SO post Can't retrieve the injector from angular