AngularJS issue injecting services - angularjs

Not really sure where I'm going wrong here. I'm trying to simply inject a service and use it in controller
app.js
var app = angular.module('myApp', [
'myApp.controllers.myCtrl',
'myApp.services.myService'
]);
js/controllers/myCtrl.js
var app = angular.module('myApp.controllers.myCtrl', []);
app.controller('homeController', function ($scope, MyService) {
...
});
js/services/myService.js
var app = angular.module('myApp.services.myService', []);
app.service("MyService", function ($http, $q) {
...
});
This results in the following error

Here you are trying to access myService service component of myApp.services.myService module in myApp.controllers.myCtrl module, without injecting the module will obviously going to get failed.
If you wanted to access the service in myApp.controllers.myCtrl module then you need to inject myApp.services.myService in the [](dependency array where you can all dependent module).
var app = angular.module('myApp.controllers.myCtrl', ['myApp.services.myService']);
By doing above line you do have all component(services) in myApp.controllers.myCtrl module.

js/controllers/myCtrl.js
var app = angular.module('myApp.controllers.myCtrl', ['myApp.services.myService']);
app.controller('homeController', function ($scope, MyService) {
...
});
Then not need to inject services in app.js again.
var app = angular.module('myApp', ['myApp.controllers.myCtrl']);

Related

Unknown Provider error creating angular.js service with require.js

I'm trying to get a service working using AMD loading with require.js. I have my controllers all working and can load $rootScope to store app-wide variables/data but I would also like to add some methods to modify or refresh some of the app-wide data when needed. Thus I was trying to create a service object in require.js
So I create this sort of a thing:
MyService.js
define( ["angular"], function (angular) {
var MyService = function($scope, $rootScope) {
this.$scope = $scope;
this.$rootScope = $rootScope
}
MyService.$inject = ["$scope"];
MyService.prototype = {
constructor: MyService,
// comma separated list of methods and properties
}
return MyService
})
I similarly define a couple of controllers (all already working fine) then access them in my require.js config something like:
requirejs(
[ "angular", "MyService", "MyController" ],
function(angular, MyService, MyController) {
let myAppHandle = angular.module('myApp',[])
.service("myService", ['$scope','$rootScope', MyService])
// the following throws an error:
// angular.js:15697 Error: [$injector:unpr]
// Unknown provider: $scopeProvider <- $scope <- myService
myAppHandle.controller('MyController', ['$scope', 'myService', MyController])
}
)
Any help is appreciated
Ahh, I was guessing in the dark at how to create a service properly in require.js and after some tinkering and banging my face on the keyboard, I eventually figured out the problem was not with the controller getting the service, but with the service getting $scope
The examples I found for require.js dealt mostly with controllers, components and directives and and in just about every case, $scope was the first thing passed in.
I took $scope out of the .service() in the definition and in the constructor for the class and it's now working.
define( ["angular"], function (angular) {
var MyService = function($rootScope) {
// using $rootScope to store app-wide variables
// accessible directly or via this service
// potentially updated/populated by methods in this service
this.$rootScope = $rootScope
}
MyService.prototype = {
constructor: MyService,
// comma separated list of methods and properties
}
return MyService
})
and
requirejs(
[ "angular", "MyService", "MyController" ],
function(angular, MyService, MyController) {
let myAppHandle = angular.module('myApp',[])
.service("myService", ['$rootScope', MyService])
myAppHandle.controller('MyController', ['$scope', 'myService', MyController])
}
)
for reference, this is what the controller looks like:
define( ["angular"], function (angular) {
var MyController = function($scope, myService) {
this.$scope = $scope
// make service handle available as class property
this.myService = myService
}
MyController.$inject = ["$scope"];
MyController.prototype = {
constructor: MyController,
// comma separated list of methods and properties
}
return MyController
})
(Hopefully this will save someone else the 2-3 hours I took figuring this out)

Failed to instantiate module myApp due to: Error: [$injector:nomod]

I am having an error on this code. I don't know why I am using angularjs 1.7.x version
$(document).ready(function () {
$('#signupBtn-spinner').hide();
var app = angular.module('myApp', []);
$('#signupBtn').click(signup);
function signup() {
app.controller('signupController', ['$scope', '$http', function ($scope, $http) {
alert('hello')
}]);
}
})
I strongly recommend you to avoid to use jquery with Angular/js
If you want to implement signup/login logic, suggest you to use ui-router. Some example.
Also please read this great Josh David Miller's answer “Thinking in AngularJS” if I have a jQuery background
About your problem:
You get this error from ng-app.
Put var app = angular.module('myApp', []); out of $(document).ready
Angularjs is loaded and it does not see any module because it is still not ready.
var app = angular.module('myApp', []);
$(document).ready(function () {
$('#signupBtn-spinner').hide();
$('#signupBtn').click(signup);
function signup() {
app.controller('signupController', ['$scope', '$http', function ($scope, $http) {
alert('hello')
}]);
}
})

Angular: How to resolve [$injector:unpr] error for $httpProvider and inject controller in jasmine test

I am new to angular testing. Facing some issues while testing angular code using jasmine.
It will be highly appreciated if you read my question and try to solve my problem as i googled it but could not find any satisfactory solution
Here is my angular app
var app = angular.module('myApp', ['ngAnimate', 'ui.router', 'ui.bootstrap', 'toggle-switch',
'ngTagsInput', 'blockUI', 'ngBootbox', 'ui.select', 'ngSanitize', 'angular.filter']);
app.config(["$httpProvider", "blockUIConfig", function ($httpProvider, blockUIConfig) {
'use strict';
blockUIConfig.autoBlock = false;
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.interceptors.push('interceptorService');
}]);
And here is controller file:
app.controller('myController', ['$scope', '$filter', '$http', '$window', '$ngBootbox', '$modal', 'dataservice', 'user', 'message_kinds',
function($scope, $filter, $http, $window, $bB, $modal, dataservice, user, message_kinds) {
$scope.user = user;
/controller logic/
}]);
I want to test this controller if $scope.user equals to user or not.Am using jasmine for testing. Here is spec file.
describe("myController", function() {
beforeEach(module('myApp'));
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
describe("myController testing", function () {
it("should update scope.user", function () {
var user = {customer_id: 1};
var my_controller = $controller('myController', { user: user });
expect(my_controller.user).toEqual(user);
});
});
});
I have also included all dependency files like angular.js, angular-mocks.js etc in SpecRunner.html
Having three problems:
Facing [$injector:unpr] http://errors.angularjs.org/1.4.4/$injector/unpr?p0=interceptorServiceProvide error on app.config block regarding $httpProvider
ReferenceError: $controller is not defined in spec.js at line
var my_controller = $controller('myController', { user: user });
How can I test if scope.user is equals to user in expect block?
1) Check this answer, as regards $http/$httpBackend which might help you - you can adapt this to get the answers you're looking for
2) Have you declared $controller (and now $httpProvider) as a variable in the beginning of the describe() block?
3) You should have that already. Your code, at least as I can see, looks like it should work like you want it to.

Angular's $interval service not found when testing using karma and mocha

I created a service that has $interval as a dependency and makes use of it and seems to work. Unfortunately when I'm trying to unit test the app $interval service is not found by angular:
Unknown provider: $$qProvider <- $$q <- $interval
I am not calling the service inside a controller as usual, but on the run() method of the app:
app.service('myService', ['$rootScope', '$window', '$interval', myService]);
app.run(function (myService) {
...
});
It works, but if I try to test the app crashes. Rest of angular services don't seem to have this problem ($window, $location, $rootScope, ...) and even this same service works if I attach my service to a controller instead than calling it at app.run():
app.controller('myController', ['myService', function(myService){ ... }]);
I use Karma+Mocha+Sinon+Chai to test.
UPDATE
Example with mini app trying to use $interval at app.run():
var anApp = angular.module('myTestApp', ['ngRoute']);
anApp.run(function($rootScope, $timeout, $window, $location, $interval) {
// blah
});
The test:
describe("Lalarala", function() {
var scope = null;
beforeEach(function() {
module("myTestApp");
inject(function ($rootScope) {
scope = $rootScope.$new();
});
});
it("doesnt crash", function () {
//blah
});
});
Note: If you remove $interval from the app.run() it works. Instead, other angular services like $timeout, $window or $location don't seem to bother.
Also, I've noticed that other services like $resource have this problem too.
I presume some of those services require something else to be there before they are ready and that's why I can't call them at app.run()?
Thanks for any help.
This line is definitely wrong.
app.controller('myController', [myService, function(myService){ ... }]);
Array injection syntax should contain strings
app.controller('myController', ['myService', function(myService){ ... }]);
Ok,
After checking many things I found the problem had to do with an angular-mocks being out of date.
I updated versions of angular and angular-mocks and now everything is working fine.
Sorry!

How to use injected dependency in a angular service?

I am creating a custom service which logs a user in to my system. In this service, I need to use core services such as $http - How do I actually depend these to be used in my service?
My current code:
.factory('loginService', ['$http', '$rootScope', function() {
var login = function(){
console.log($http);
}
return {login : login};
}])
I call the login function from a controller like so
loginService.login();
I hoped that my console will output the $http object I injected, but it's returning undefined.
How do I access this in the correct way?
You need to add the dependencies to your function arguments:
.factory('loginService', ['$http', '$rootScope', function($http, $rootScope) {
//You can use $http and $rootScope here now
}
See the official docs for more info on Dependency Injection in angular
Services you inject need to be passed as arguments of the function:
['$http', '$rootScope', function($http, $rootScope)
By the way, you'll need to do the same where you're trying to use it:
app.controller(['loginService', function (loginService) {
loginService.login();
});
try this:
var myapp = angular.module('mainApp', []);
myapp.controller('myController', ['$scope', 'myFactory', function($scope, myFactory) {
myFactory.login();
}]);
myapp.factory('myFactory', ['$http', function($http) {
var services = {};
services.login = function() {
console.log($http);
}
return services;
}]);
View:
<div ng-app='mainApp' ng-controller='myController'></div>

Resources