Rectangle 27 9

You can inject constants and other providers into a provider. Not services or factories - with one exception. It seems that you can inject the $injector service into a provider - at least, you can in AngularJS 1.3.16.

.provider('foo', ['$injector', function ($injector) {
  var messagePrefix = $injector.get('msgPrefix');
  this.message = '';

  this.$get = function() {
    var that = this;
    return function() {
      return messagePrefix + that.message;
    }
  };
}])

You can use the injector outside the $get method, but you still can't get services from it at configure time.

How to inject dependencies into a provider using Angularjs? - Stack Ov...

angularjs
Rectangle 27 6

You forgot to pass the name of the factory in the array. Typically you pass an array whose elements consist of a list of strings followed by the function itself. Be sure to keep the array in sync with the parameters in the function declaration. This way the injector knows what services to inject into the function.

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) {

This is how I would do it...When routes are used I like to use resolve so the data gets loaded once and is stored. So in the $routeProvider, I would change the the smController part to the following...

when('/sm', {
      templateUrl: 'partials/sm.html',
      controller: 'smController',
      resolve:{
              load:function(stadtMobilRates){
                  return stadtMobilRates.LoadData();
          }
    }).

I've also modified the factory

myApp.factory('stadtMobilRates', function ($q, $http) {
var mobilRates = null;

function LoadData() {
    var defer = $q.defer();
    $http.get('stadtmobilRates.json').success(function (data) {
        mobilRates = data;
        defer.resolve();
    });
    return defer.promise;
}

return {
    GetData: function () { return mobilRates ; },
    LoadData:LoadData
}
});

So before this route is loaded, it's going to call the LoadData function in the factory. Once the data gets loaded, it resolves the promise so this LoadData function will only get called once. Once the promise resolves, it will go ahead and load the view.

So now in your controller, whenever you want to get the data, all you have to do is call the function GetData

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) 
{
     var stadtmobilRates = stadtMobilRates.GetData();
});

Is the data even set when you log it? Try putting the console.log(stadtmobilRates); inside the success function, not after it.

You are programming async. Put your console.log inside the callback.

Is in your project URL to json file in $http request correct?

It works on a simplified question of my app, however not with routes. I've updated the question.

javascript - Loading json data with an AngularJS factory - Stack Overf...

javascript json angularjs factory
Rectangle 27 6

You forgot to pass the name of the factory in the array. Typically you pass an array whose elements consist of a list of strings followed by the function itself. Be sure to keep the array in sync with the parameters in the function declaration. This way the injector knows what services to inject into the function.

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) {

This is how I would do it...When routes are used I like to use resolve so the data gets loaded once and is stored. So in the $routeProvider, I would change the the smController part to the following...

when('/sm', {
      templateUrl: 'partials/sm.html',
      controller: 'smController',
      resolve:{
              load:function(stadtMobilRates){
                  return stadtMobilRates.LoadData();
          }
    }).

I've also modified the factory

myApp.factory('stadtMobilRates', function ($q, $http) {
var mobilRates = null;

function LoadData() {
    var defer = $q.defer();
    $http.get('stadtmobilRates.json').success(function (data) {
        mobilRates = data;
        defer.resolve();
    });
    return defer.promise;
}

return {
    GetData: function () { return mobilRates ; },
    LoadData:LoadData
}
});

So before this route is loaded, it's going to call the LoadData function in the factory. Once the data gets loaded, it resolves the promise so this LoadData function will only get called once. Once the promise resolves, it will go ahead and load the view.

So now in your controller, whenever you want to get the data, all you have to do is call the function GetData

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) 
{
     var stadtmobilRates = stadtMobilRates.GetData();
});

Is the data even set when you log it? Try putting the console.log(stadtmobilRates); inside the success function, not after it.

You are programming async. Put your console.log inside the callback.

Is in your project URL to json file in $http request correct?

It works on a simplified question of my app, however not with routes. I've updated the question.

javascript - Loading json data with an AngularJS factory - Stack Overf...

javascript json angularjs factory
Rectangle 27 12

The point that BinaryMuse makes in her amazing answer about providers, factories, and services all being the same thing extremely important.

Below is an image that I think can visually illustrate her point:

angularjs - What "things" can be injected into others in Angular.js? -...

angularjs dependency-injection
Rectangle 27 1

After seeing this question How to Inject my service to ExceptionHandler I think this could be a solution for your problem. If you control one of the classes of the cyclic depenencies, you can just inject the Injector to the constructor and then acquire the instance you actually want:

constructor(injector:Injector) {
  setTimeout(() => this.someService = injector.get(SomeService));
}

javascript - Cyclic dependency , when ovveriding ExceptionHandler - St...

javascript angularjs dependency-injection typescript angular
Rectangle 27 1

After seeing this question How to Inject my service to ExceptionHandler I think this could be a solution for your problem. If you control one of the classes of the cyclic depenencies, you can just inject the Injector to the constructor and then acquire the instance you actually want:

constructor(injector:Injector) {
  setTimeout(() => this.someService = injector.get(SomeService));
}

javascript - Cyclic dependency , when ovveriding ExceptionHandler - St...

javascript angularjs dependency-injection typescript angular
Rectangle 27 4

During the config phase, only providers can be injected. So I think that you can create a custom provider and then configure it during the config phase.

Basically angularjs first invoke the config method and then invoke the run method. During config only providers are available. A provider can then be used to create service instance.

I may be incorrect, but aren't constants also available in the config phase? docs.angularjs.org/guide/providers#conclusion

javascript - AngularJS - How can I use .config() method with my own se...

javascript angularjs
Rectangle 27 2

Because you are trying inject directive into controller. It doesn't make sense - you can only inject services.

Why directives are not injectable? Clearly, one might want to use its API from controller? Well, the reason why is the core or Angular app architecture. Directives being part of view layer of the application, should not be interacted from controller directly. Another important thing to understand is that services (what you inject) is intentionally singletones - while directives cannot be, of course.

In your case you don't need to worry about it: directive is registered on the same module so it's available in template.

Correct controller definition would be:

.controller('RandomBusinessCtrl' [
    '$scope', 'pickRandomBusinesses', 'BusinessViewModel', 'config',
    function ($scope, pickRandomBusinesses, BusinessViewModel, config) {

});

Man you are the best.. Thanks alot ..for the information ..though i lost my button cant see it on the interface anymore

Glad it was useful. Why your button is gone - something is with your app, from the posted code it's not possible to say.

i think the name of tag and directive doesn't match

angularjs - why does my directive throws $unknown provider - Stack Ove...

angularjs angularjs-directive
Rectangle 27 1

I was forgetting to inject the file that held my services altogether. Remember to do this when initializing your app module:

angular.module('myApp', ['myApp.services', ... ]);

angularjs - angular js unknown provider - Stack Overflow

angularjs
Rectangle 27 0

It is possible to ask AngularJS to instantiate your own objects (and inject dependencies into them!) by using the $injector service and its instantiate(Type, locals) method.

var Item = function ($filter, name, price) {
    var self = this;

    self.name = name;
    self.price = price;

    self.pretty = function () {
        return $filter('json')(self);
    };
};

one could create an instance of Item like so:

var item = $injector.instantiate(Item, { name: $scope.name, price: $scope.price });

Please note that the instantiate method accepts 2 arguments:

  • Type: a constructor function.
  • locals: a hash of values that should not be injected but rather taken as-is.

Here is a working jsFiddle (a simplified version of the initial one).

This is exactly what I was looking for. I had looked at $injector doc page, but missed instantiate(type, locals)... Sigh...

javascript - Have AngularJS inject dependencies into objects like it a...

javascript dependency-injection angularjs
Rectangle 27 0

Because of the way DI works - you shouldn't have to create instances of your services, ever really. What you do is you inject the service(s) you need into your controller and it should just work. In the case above, your controller might be defined to be:

The only other thing you need to do here is make sure that "App" is the name you specify in the "ng-app" directive and make sure that your page includes the JS files with "DataProcessor" before you include the angular app module (technically these could even be defined in the same file). Hope this helps!

By the way, if you need to minify - the following is how you would define the controller:

var app = angular.module('App', ['DataProcessor']);

// if you need to minify:
var MyController = ['$scope', 'DataProcessor',
    function($scope, DataProcessor) {
        var uri = '';
        DataProcessor.processData(uri);
    }
];

My understanding of a service at the present time is that is is used to shared data or code between controllers. If this data processing is specific to that controller you might consider just moving the "ProcessData" implementation directly into your controller. Sometimes changes like this can be simpler than processing the data in a service. If you do process the data in the service you might still want to write that data back to the scope. In this case, you can pass $scope as a parameter into the service routine. Since I don't know too much about your use case, just take these suggestions with a grain of salt. Good luck!

But if the DataProcessor needs a specific implementation of a DataReader (e.g. JsonDataReader), how do you do that? A major benefit of dependency injection is the ability to swap implementations. All the examples I've found in AngularJS have their "dependencies" injected, but they're always just pointing to a single, specific concrete implementation of something.

I agree with what you are saying. One way I can think of swapping the implementation would be to have two JS files that defined the same service and use the include (script include, that is) to decide which will be used by the controller. Overall, I don't think JavaScript supports classical inheritance which makes some of the DI concepts more difficult.

AngularJS dependency injection swap implementation - Stack Overflow

angularjs angularjs-injector
Rectangle 27 0

As you suggest using ngRoute, you could just inject the $rootParams-service into your controllers and get all the current params. If you also need the current controller selected by ngRoute, you should inject the $route-service as well. See the example in the ngRoute documentation for more details on how to use these services - or provide a (minimal) version of your angular code to give you an example based on your use case.

BTW: If you also have different views and/or layouts (for example not only video) in your SPA, you could use ngRoute's ng-view directive to set up a viewport for all these different layouts. In that way each layout can have it's own template and a layout specific controller that can reuse generic controllers and directives (for example for comments). Again I need more code to give an meaningful example for that.

AngularJS - Managing URL changes across multiple controllers / UI elem...

angularjs angularjs-directive angular-ui
Rectangle 27 0

You are getting a circular dependency error since the $modal service has dependency on $http. This is a common problem with $http interceptors that got dependency on $http themselves. Fortunately the remedy is simple: you need to inject $injector into your interceptor and retrieve $model from the injector like so:

app.factory('AuthInterceptor', function ($rootScope, $q, $injector) {
    return {
        responseError: function (res) {

            var $modal = $injector.get('$modal');

            if (res.status === 401) {
                //you can use $modal here...
                console.log('AuthInterceptor says you are not authorized');
            }
            if (res.status === 404) {
                console.log('AuthInterceptor says this page is not found');
            }
            return $q.reject(res);
        }
    };
});

Thank you, that worked and gave me a better understanding of the circular dependency that was happening. Do you have any tips on checking if a modal is currently open? For an example involving this http interceptor. I have a modal login form. Thanks to you I can now open this modal whenever a 401 status code is intercepted. The login form itself will send a 401 status code when invalid credentials are entered and will then stack a new login modal atop the original. How might I avoid this?

javascript - Trying to fire a ui-modal on a 401 server response - Stac...

javascript angularjs
Rectangle 27 0

It is better to share common code through services. Just create a service using one of the Angular provider models and inject it wherever it's needed.

Hi TGH, As I am new to AngularJS, I don't know how to do it in services. Is it possible or not using same controllers ??

@Shanmugam, look at the service documentation docs.angularjs.org/guide/services and think of how it would apply to your application structure. You can use the same code in both controllers, but it is bad practice and not recommended.

Use same controller for two different modules in angularJS - Stack Ove...

angularjs
Rectangle 27 0

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.

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!

THank you, it is a lot clearer when i see it in context like this.

The best way to Mock Services in AngularJS to decouple REST calls - St...

angularjs
Rectangle 27 0

The magic is done by $injector.annotate:

Returns an array of service names which the function is requesting for injection. This API is used by the injector to determine which services need to be injected into the function when the function is invoked. There are three ways in which the function can be annotated with the needed dependencies.

The first way is to extract the names of the arguments from the function signature:

The simplest form is to extract the dependencies from the arguments of the function. This is done by converting the function into a string using toString() method and extracting the argument names.

In JavaScript calling toString() on a function returns the function definition. The definition can then be parsed and the function arguments can be extracted. NOTE: This does not work with minification, and obfuscation tools since these tools change the argument names.

From the source code , how $injector extracts arguments from a function:

if (fn.length) {
  fnText = fn.toString().replace(STRIP_COMMENTS, '');
  argDecl = fnText.match(FN_ARGS);
  forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
    arg.replace(FN_ARG, function(all, underscore, name){
      $inject.push(name);
    });
  });
}

angularjs - How angular knows which service to inject? - Stack Overflo...

angularjs
Rectangle 27 0

Providers are available in a phase before any solid services or other components are ready, so you won't be able to inject your service directly into the provider.

You can, however, inject services into the $get function of your provider, used when you actually instantiate a service. So your loginProvider cannot access templateSrv but your login service can do, so long as the module in which templateSrv is defined 'requires' that in which loginProvider is defined. It appears to be doing this in your example (angular.module('loginProvider', ['templatesServices'])) but the fiddle seems very different.

var templateModule = angular.module('templateModule', []);
templateModule.factory('templateSrv',[function(){ 
    return {
        // ...
    };
}]);

function loginProvider(){
    this.$get = ['templateSrv', 'otherService', function(templateSrv, otherService) {
      // Use templateSrv/otherService (from templateModule or loginModule) somehow
    }];
    this.getAccess = function(){
        return 'some data';
    };
}

angular.module('loginModule', ['templateModule'])
    .provider('login', loginProvider);

Yes the idea is to use the service "factory" in service "provider". This is useful when you need setup the module and can only use service "provider" with other services that you have. runing jsfiddle.net/aurigadl/facgT/9

javascript - how should be used a service "factory" in a provider of a...

javascript angularjs service provider
Rectangle 27 0

Have a look at the documentation for module and have a read at the comments in the example setup, particularly these comments.

You can only inject Providers (not instances) into config blocks

You can only inject instances (not Providers) into run blocks

angular.module('myModule', []).
  config(function(injectables) { // provider-injector
    // This is an example of config block.
    // You can have as many of these as you want.
    // You can only inject Providers (not instances)
    // into config blocks.
  }).
  run(function(injectables) { // instance-injector
    // This is an example of a run block.
    // You can have as many of these as you want.
    // You can only inject instances (not Providers)
    // into run blocks
  });

AngularJs can't inject $provide and $injector services in module.run -...

angularjs
Rectangle 27 0

You're looking for the Module.run() method, It does initialization work for you after the injector is done loading.

angular.module('myApp', ['app.services'])
   .run(function(myservice) {
      //stuff here.
   });

No sweat. I miss stuff in docs all the time. lol.

javascript - How do you inject services from required modules into mod...

javascript angularjs
Rectangle 27 0

You can't do this. Provider will be registered during the configuration phase. And in this phase the services are not yet available for injection. See http://docs.angularjs.org/guide/module - Module Loading & Dependencies

Also checkout http://docs.angularjs.org/guide/providers. There you will see what is available during configuration phase.

hi @Mchael, so in my case I should just fall back to using factories instead? Or can I perhaps inject into the $get function somehow?

thank you very much for your help Michael, it works.

angularjs - How should I inject into provider? - Stack Overflow

angularjs