im completely new to angularJS, below is the minimal example of my issue:
myModule.module.js:
(function () {
'use strict';
angular
.module('myModule', [
'myServices',
'myControllers'
]);
angular
.module('myServices', []);
angular
.module('myControllers', []);
})();
myService.service.js
(function () {
'use strict';
angular
.module('myModule')
.factory('myServices', myServices);
function myServices() {
var service = {};
return service;
}
})()
myController.js:
(function () {
"use strict";
angular
.module("myModule")
.controller("myController", myController);
myController.$inject = ['myServices']
myController(myServices) {
/* use myServices */
}
})()
I think I accomplished all things needed to make service available to controller but I'm still getting unresolved provider error...
I'm coming from strong Angular2+ background and maybe some common potfall I'm unaware of? Does the tile names os services must match their angular name or something similar?
Any help is appreciated.
Oh yeah, Angular2+ experience strikes on this one. Basically I was absolutely unaware about managing scripts in main.html (or whatever entry point for app is). So basically I was dumb enough not tu supply my main.html with specified script file.
So, assuming that my usecase was to add just another service to already working myModule, then
<script src="path/to/myService.js"></script>
Hope this will help someday some other dev lost in AngularJS :)
Cheers
Related
I am trying to get angularjs to play nicely with local templates that override bootstrap ones.
I had initially use the same file path (uib/template/carousel/carousel.html for example) which is fine when published, but locally it doesn't work.
So, I found this soluton:
Angular ui bootstrap directive template missing
They have said you can override the template with a new url with the $provide service.
So I have done this:
'use strict';
angular.module('core').config(coreConfig);
function coreConfig($provide) {
$provide.decorator('uibCarousel', function ($delegate) {
console.log($delegate[0]);
$delegate[0].templateUrl = 'bootstrap/carousel/carousel.html';
return $delegate;
});
};
which should work.
my core module looks like this:
'use strict';
angular.module('core', [
'ngCookies',
'ngNotify',
'ngResource',
'ngSimpleCache',
'ui.bootstrap',
'ui.bootstrap.tpls',
'ui.router',
'ui.select',
// -- remove for brevity -- //
]);
As you can see, I have the ui.bootstrap.tpls module loaded, so in theory, my code should work.
Can anyone think of a reason that it won't?
Sorry for all the comment spam. I think I have found the answer to your issue.
You must append Directive to a directive when defining the decorator:
function coreConfig($provide) {
$provide.decorator('uibCarouselDirective', function ($delegate) {
console.log($delegate[0]);
$delegate[0].templateUrl = 'bootstrap/carousel/carousel.html';
return $delegate;
});
};
From the docs:
Decorators have different rules for different services. This is
because services are registered in different ways. Services are
selected by name, however filters and directives are selected by
appending "Filter" or "Directive" to the end of the name. The
$delegate provided is dictated by the type of service.
https://docs.angularjs.org/guide/decorators
This is an example from my own (working) code:
$provide.decorator("uibDatepickerPopupDirective", [
"$delegate",
function($delegate) {
var directive = $delegate[0];
// removed for brevity
return $delegate;
}
]);
I have Angular 1.4 service working in app.js but I want to move this service in a separate file. Can anybody advise me a site explaining how to do this? Thanks!
Heres an example of how you can move your service in a separate file.
app.js:
(function(){
// create main app module
angular.module('myApp', []);
})();
controller.js:
(function(){
angular.module('myApp').controller(MyController, MyController);
// inject dependencies here
MyController.$inject = ['MyService'];
function MyController(MyService) {
// controller logic
}
})();
service.js:
(function(){
angular.module('myApp').factory('MyService', MyService);
MyService.$inject = [];
function MyService() {
var service = {};
return service;
}
})();
As for a site with good explanations and best practices, check out the angular 1.x style guide which has been endorsed by the angular team. Specifically pay attention to Style Y001.
I have enabled strict-di on my application as I am trying to prepare my source code for minification and am now working through resolving strictdi errors being thrown.
I have the following controller thats throwing a strictdi error, but I am correctly annotating using $inject (I am using the John Papa style guide too) and I cannot figure out where I am going wrong:
(function () {
'use strict';
angular
.module('app.products')
.controller('ProductsPageController', Controller);
Controller.$inject = ['MyToolbarService'];
function Controller(MyToolbarService) {
MyToolbarService.getToolbar('main').then(function (toolbar) {
toolbar.setTitle('GENERAL_TERMS.PRODUCTS');
});
}
})();
Error: [$injector:strictdi] ProductsPageController is not using
explicit annotation and cannot be invoked in strict mode
I have another controller (below) that works in exactly the same manner, and when the view loads that this is bound, no error is thrown and my toolbar service is setting its title:
(function () {
'use strict';
angular
.module('app.home')
.controller('HomePageController', Controller);
Controller.$inject = ['MyToolbarService'];
function Controller(MyToolbarService) {
MyToolbarService.getToolbar('main').then(function (toolbar) {
toolbar.setTitle('GENERAL_TERMS.WELCOME_MESSAGE');
});
}
})();
Banging my head against the wall now! Anyone got any suggestions?
Thanks
I typically don't write my DI in this fashion, most of the time I pass the array as the second argument to the .controller() function.
As to why you are having issues I am not sure. Could it be indentation? (crazy as it seems).
If you wanted to rule anything out I suppose you could try and write it:
(function () {
'use strict';
angular
.module('app.home')
.controller('HomePageController', ['MyToolbarService', Controller]);
function Controller(MyToolbarService) {
MyToolbarService.getToolbar('main').then(function (toolbar) {
toolbar.setTitle('GENERAL_TERMS.WELCOME_MESSAGE');
});
}
})();
I've scaffolded my Laravel/Angular app and have an app/ directory in project/public/assets/
Inside of the app directory I have an app.js file, and directories for controllers/, filters/, etc.
Rather than loading each individual controller, filter, etc.. how can I load all of them in the directory?
Yeah, as #cbass rightly said you should concatenate them. Its recommended to concat it for production build, however you can try using this following structure to experiment
(function () {
angular.module('app', []);
// MainCtrl.js
function MainCtrl () {
}
angular
.module('app')
.controller('MainCtrl', MainCtrl);
// AnotherCtrl.js
function AnotherCtrl () {
}
angular
.module('app')
.controller('AnotherCtrl', AnotherCtrl);
// and so on...
})();
About code snippet referred from Todd Motto's blog
Whenever I do this:
app.controller('hangmanController', ['$scope', 'wordnickAPIService', function ($scope, wordnickAPIService) {
I get this:
[$injector:unpr] Unknown provider: wordnickAPIServiceProvider <- wordnickAPIService
I read through This discussion on the topic, but didn't see an answer that applied. I am sure it is something simple or trivial that I am missing, but, jeez, if Angular isn't giving me fits trying to piece it all together.
Relevant HTML:
<body ng-app="angularHangmanApp" ng-controller="hangmanController">
My controller:
'use strict';
var app = angular.module('angularHangmanApp', []);
app.controller('hangmanController', ['$scope', 'wordnickAPIService', function ($scope, wordnickAPIService) {
[...]variable declarations[...]
var wordListURL = 'http://long_url_that_returns_some_json';
$scope.wordList = wordnickAPIService.get(wordListURL);
}]);
My factory:
'use strict';
var app = angular.module('angularHangmanApp', []);
app.factory('wordnickAPIService', ['$http', function($http) {
return {
get: function(url) {
return $http.get(url);
},
post: function(url) {
return $http.post(url);
},
};
}]);
The problem is that you are creating multiple modules with the same name.
To create a module in angular you use:
var app = angular.module('angularHangmanApp', []);
Then to get That module somewhere else you just type:
var app = angular.module('angularHangmanApp');
No extra []...
Also make sure you declare the service before trying to call it.
In your factory and your controller, you are actually redefining the app module.
Instead of saying
var app = angular.module('angularHangmanApp', []);
say
var app = angular.module('angularHangmanApp');
Use the first style of invocation only once in your application (maybe just app.js). All other references should use the second style invocation, otherwise, you're constantly redefining the angular app and losing all of the controllers, factories, directives declared previously.