Angular : Can't access injected dependency constant - angularjs

I'm using Webpack 1.13.2 with Angular 1.5.8 and I can't manage to access my "SETTINGS" constant from my poiService file.
TypeError: Cannot read property 'API_URL' of undefined
http://plnkr.co/edit/6repllAk39kv4Enfw8RU?p=catalogue
Thanks for help.

PoiService has mismatching annotation:
services.factory('PoiService', ['SETTINGS', require('./poiService')])
service definition and
module.exports = function ($http, SETTINGS) { ... }
function signature.
For this reason it may be not advisable to keep factory function and service definition in separate files. And even if there's a need to do this, it is preferable to use named function and $inject annotation instead of inline array annotation:
services.factory('PoiService', require('./poiService'))
...
poiService.$inject = ['$http', 'SETTINGS'];
function poiService($http, SETTINGS) { ... }
module.exports = poiService;

Related

How to access AngularJS service/factory in CKEditor custom plugin

I am using CKEditor 4 in an AngularJS app. I have a directive for CKEditor which sets the editor options
angular.module('someMod', []).directive("ckeditor", CKEditor).factory('someFactory',someFactory);
...etc...
CKEditor.$inject = ["someFactory"];
function CKEditor(someFactory) {
...and in the link function the editor options includes...
extraPlugins: 'myplugin'
Now if I put the custom plugin definition into the link function it works fine because it can reference someFactory no problem. But I want to put all the "myplugin" code into a separate plugin file. And this works fine except when it tries to reference someFactory it fails.
Edit ------
The factory is constructed as follows
someFactory.$inject = ['$http', '$log', ...];
function someFactory($http, $log, ...) {
return {
someFunction: someFunction,
...
};
function someFunction() {
// do some stuff
return 1;
}
Anyone know how to make someFactory available to the CKEditor plugin?
A factory must return an object. If it has not been setup properly that could cause the issue you are experiencing. Would require a more complete example to troubleshoot.
I found a way to do this. I declare a global variable like
var angularObject = {};
Then in the CKEditor directive link function I add
angularObject = someFactory
to create a reference to the factory that was injected into the directive. Then in the plugin code I can say something like
angularObject.someFunction

Testing a class that uses $inject property notation in its functions

I need to modify a constant service. This service has no tests attached, but I wanted to, at least partially, cover the file and my modifications with unit tests that I will write with Jasmine.
The service looks like:
(function () {
angular
.module('app')
.constant('myService', myService);
function myService() {
dependencyOne: dependencyOneImpl,
someFunction: someFunctionImpl
...
}
dependencyOneImpl.$inject = ['someDependency'];
function dependencyOneImpl(someDependency) {
...
}
someFunctionImpl.$inject = ['dependencyOne', 'dependencyTwo'];
function someFunctionImpl(dependencyOne, dependencyTwo) {
...
}
})();
It is used in the resolution process of routes (we use ui-router). When a particular route is activated, a function of the service is invoked:
someRoute = {
url: '...',
name: '...'
views: { ... },
resolve: { resolver.someFunction }
}
There are no dependencies required in the construction of the service, and I'm trying to test one of the public functions that the service exposes.
Typically I would write the test like:
prepareSomeSetup();
theService.someFunction();
assertSomething();
I could manually resolve the dependencies required by the function, but I would like to know if I can get the same behavior that ui-router is getting when resolving the function. The dependencies seem to be resolved and the function is executed.
It crossed my mind that I probably needed to inject $injector service in the test file and manually call invoke somehow to resolve the function, but it does not seem to work.
How can I call the function with the two dependencies resolved?
When you define an injectable function you have to call it using $injector.invoke(fn, scope, otherArgs);
Where
fn the injectable function, or array for inline injection
scope : the "this" of the function
otherArgs : others Arguments that are not defined as service,... in angular that you inject.

Unable to inject service in angular js

I'm constantly failing to inject the $log service in a minify save way into a controller class of a component.
To check the injection is save, I added ng-strict-di to my app. This in terms causes an SearchResultController is not using explicit annotation and cannot be invoked in strict mode which is fine, since I'm relying on implicit injection right now.
So I added an explicit injection to my component implementation:
import htmlTemplate from './searchInput.html';
class SearchInputController {
constructor($log) {
this._log = $log;
this.searchText = 'Text to search for';
}
handleUpdate() {
this.onChange({value: this.searchText});
}
doubleMe(i) {
this._log.debug('SearchInputController.doubleMe: i='+i);
return i+i;
}
}
SearchInputController.$inject = ['$log'];
let searchInputComponent = {
template: htmlTemplate,
controller: SearchInputController,
bindings: {
onChange: '&'
}
};
export default searchInputComponent;
This has no effect the error message is still complaining about the missing injection.
I also tried ng-annotate-loader and ng-annotate-webpack-plugin. And also tried the /*#ngInject*/ and 'ngInject'; type annotations. All of this has no effect.
Any ideas how to get the dependency injection working?
Your annotation appears to be correct for SearchInputController, but the error message is complaining about a different controller SearchResultController. I suggest you need to annotate that one also.
Use https://babeljs.io/repl/ to check how ES6 compiles down to ES5. This can be useful when trying to trace errors in annotation. Using ng-annotate in some form should also work when you annotate the correct controller.

Injecting and using a service into my provider then using the provider in the config block

I am trying to inject a custom factory from one module into a custom provider from another module. What I really want to do is to use the custom factory inside the config block but I can't, so I'm trying to configure a provider that uses the custom factory which will then get injected into config.
I have been trying to inject my custom factory into the provider but I can't seem to get it right. I don't know if it's syntax or maybe my approach is wrong. My questions are:
1.) is this even possible?
2.) is my syntax correct?
Here is the factory:
.factory('myFactory', myFactory);
myFactory.$inject = ['$q', '$http', 'Story'];
function myFactory($q, $http) {
return {
getSomething: getSomething,
}
function getSomething() {
}
}
Here is the provider:
.provider('myProvider', function() {
return {
$get: function(myFactory) {
function getStuff() {
return myFactory.getSomething().then(function(data){
return data;
})
}
return {
stuff: getStuff
}
}
}
})
The error that I am getting is this:
Cannot read property 'getSomething' of undefined
Is this the correct use of a provider? I feel like I may be missing something. Thanks!
During the configuration phase, you can't access services:
During application bootstrap, before Angular goes off creating all
services, it configures and instantiates all providers. We call this
the configuration phase of the application life-cycle. During this
phase, services aren't accessible because they haven't been created
yet.
https://docs.angularjs.org/guide/providers

Restangular has no method one. AngularJs inejctions

Im having problem with injections.
app.js
angular.module('Help', []);
var app = angular.module('app', [
'restangular'
,'Help'
]);
app.$inject = ['RestangularProvider'];
app.config(
function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://localhost:8080/api');
}
)
help.js
function HelpCtrl($rootScope, $scope, Restangular){
Restangular.one('questions').getList();
}
HelpCtrl.$inject = ['$scope', '$rootScope','Restangular']; //"TAG1"
angular.module('Help').controller("HelpCtrl", HelpCtrl);
I get the following error:
Uncaught TypeError: Object [object Object] has no method 'one'
If I remove line TAG1, everything works. However I need to inject it the right way. What is the problem here?
The injector is used to help AngularJS know the order of parameters given to the function in case the variable name change (e.g. after minimizing your JavaScript).
In your case, you've switched up the order of your injector parameters and the method signature, meaning that AngularJS will think that $scope is $rootScope and vice versa.
Either remove your $inject or make sure the parameters are in the same order in both your method signature and in your injection array.

Resources