Angularjs: a good way to configure callbacks that services use in providers

I need to set up callbacks inside the corner provider.

myApp.config(function(SomeProvider) { SomeProvider.defaultCallback = function(foo, bar) { console.log("foo: " + foo + ", bar: " + bar); } }) 

The problem is that I want to use services in these callbacks. In this example, I would like to use $log.log instead of console.log .

I cannot embed all of these services in my configuration block because they do not exist yet.

The question is how to use services in these configurable callbacks?

+4
source share
4 answers

Found a solution:

You must have a $ injector available. Therefore, every time a callback is called, the $ injector must be passed to:

 myApp.config(function(SomeProvider) { SomeProvider.defaultCallback = function(foo, bar, $injector) { var $log = $injector.get("$log"); $log.log("foo: " + foo + ", bar: " + bar); } }) // ... callbacks will be called this way: myObject.theCallback(foo, bar, $injector); 
+4
source

I know this is an old question, but I had this problem too, and I found a more elegant solution that could help someone. Please note that my examples are written in coffeescript.

maklemenz is right about using the $injector service, but it must remain hidden in your provider code:

 angular.module("myModule").provider "myService", () -> defaultCallback = () -> this.setDefaultCallback = (callback) -> defaultCallback = this.$get = ["$injector", ($injector) -> { #...service code... #when you want to invoke your callback: $injector.invoke defaultCallback #...more service code... }] return this 

The main advantage of this approach is that you can use any regular angular attachments in your callback:

 #using implicit injection (not minification-safe!) angular.module("myApp").config (myServiceProvider) -> myServiceProvider.setDefaultCallback ($log) -> $log.log "some message" 

This is the simplest use of the $injector.invoke method. It provides more flexibility, so check out the documentation for it.

+1
source

Just look at this post: dynamic provider settings through AngularJS application configuration

As I said in IMHO comments, you cannot use the service in the configuration block (in the callback or not).

The solution in this thread is to use the jQuery API to make a call and then to load angular ...

0
source

I had a similar problem when I needed a specific service in a callback in the configuration block, but I did not have access to the callback provider. I found that injecting the $ injector into the configuration block itself does not work, because the installation of the service is not guaranteed, and most likely it seems to you that you get the state of the nozzle from the moment you start config, and not when calling the callback. Given that I could not change the actual callback to always inject the injector directly, the only way to make it work is to grab the injector from dom. So you will get something like this (pay attention to the styles of the ES6 class!) ...

 class AppAuth { static configure($authProvider) { $authProvider.configure({ apiUrl: '', handleAccountUpdateResponse: (response) => { const injector = angular.element(document.getElementById('app')).injector(); const Client = injector.get('Client'); response.data.clients.forEach((client, index, clients) => { clients[index] = new Client(client); }); return response; } }) } } export default AppAuth 

A bit hacked, but the requirement is pretty standard, I wrap the related records (clients in the example) with the local model shell (Client). The library (ng-token-auth) sets the callback to the configuration block and wants to have a direct function with one parameter, without the ability to pass $ to the injector. Hope this helps someone with a similar situation.

0
source

All Articles