I have an angularjs project with 6 services. Everyone of them works fine, but now if i create a new service and try to inject it, it fails. I tried to inject the same service in another project and it works.
Here is the service:
app-services/test.service.js
(function () {
'use strict';
angular
.module('app')
.factory('TestService', TestService);
TestService.$inject = ['$scope'];
function TestService($scope) {
var service = {};
service.Test = Test;
return service;
function Test() {
//Stuff
}
}
})();
Here is the controller in which i try to inject it: app-index/functions/functions.controller.js
(function () {
'use strict';
angular
.module('app')
.controller('FunctionController', FunctionController);
FunctionController.$inject = ['$scope', 'FlashService', '$location', 'UploaderService', '$q','TestService'];
function FunctionController($scope, FlashService, $location, UploaderService, $q, TestService) {
var vm = this;
var fileContainers;
$scope.UploadFile = UploadFile;
function UploadFile() {
TestService.Test();
}
}
})();
In the index.html
<script src="app.js"></script>
<script src="app-services/test.service.js"></script>
<script src="app-index/functions/functions.controller.js"></script>
Error
HTML1300: NavegaciĆ³n realizada.
localhost:44373
Error: [$injector:unpr] http://errors.angularjs.org/1.6.0/$injector/unpr?
p0=TestServiceProvider%20%3C-%20TestService%20%3C-%20FunctionController
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:44:389)
at d (https://code.angularjs.org/1.6.0/angular.min.js:42:60)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:44:449)
at d (https://code.angularjs.org/1.6.0/angular.min.js:42:60)
at e (https://code.angularjs.org/1.6.0/angular.min.js:42:298)
at instantiate (https://code.angularjs.org/1.6.0/angular.min.js:43:242)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:93:137)
at link (https://code.angularjs.org/1.6.0/angular-route.min.js:7:316)
at Anonymous function
(https://code.angularjs.org/1.6.0/angular.min.js:16:45)
at ta (https://code.angularjs.org/1.6.0/angular.min.js:84:35) <div
class="ng-scope" style="width: 100%; height: 100%;" ng-view="">
As i said, the other services injected in the controller are working. And I don't think the problem is in TestService since it is working on another project.
I'm developing in Visual Studio
Edit: I removed $scope from service, but it still doesn't work
Edit 2: It looks like the problem is the caching. It loads the old version of index.html that hasn't got the reference of the new service..
Related
I'm trying to do a simple $anchorScroll but my controller is not working.
here's my module
(function () {
'use strict';
angular.module('app', [
'ui.bootstrap',
'app.article'
]);
})();
and here's my controller
(function () {
'use strict';
angular
.module('app.article')
.controller('Article', Article);
function Article($scope, $location, $anchorScroll) {
var vm = this;
vm.backToTop = backToTop;
function backToTop() {
$location.hash('top');
$anchorScroll();
}
}
})();
I'm adding the ng-app and the ng-controller correctly.
Any ideas?
here's the plunkr: https://plnkr.co/edit/Rnsahf24ds1pYWKz9Ete?p=preview
There are few things that you are missing in your code,
(i) You are refering to angular2 script while your code is defined for angular 1.3, so change the reference as
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script>
(ii) You need to refer to bootstrap library and necessary css if you are injecting in angular application
<script type="text/javascript" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"></script>
Here is the working App
I have this controller A which I'm trying to inject in every other controller.
What controller A does is, it communicates with a factory (which does some authentication services, communicates with database)
My factory looks like this and I named it myFactoryServices.js and included the link to it in my index page.
(function() {
angular
.module('myApp.myFactoryServices', [])
.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
})();
and my Controller A looks like this:
(function() {
angular
.module('myApp.ControlA', [])
.controller('ControllerA', function($scope,$routeParams, FactoryService) {
var my = this;
FactoryService.someFunction();
});
})();
And I am trying to inject this controller in every other controller, but it does not work. I am pretty new to this kind of programming, can anyone tell me where I made mistake?
This is how I tried injecting a controller into another.
(function() {
angular
.module('myApp.ControlB', [])
.factory('ControllerBService', function($http) {
var baseUrl = 'backendurl/';
return {
getInfo: function() {
return $http.get(baseUrl+ 'getInfo');
}
};
})
.controller('ControllerB', function($scope,$routeParams, ControllerBService,ControllerA) {
var my = this;
});
})();
No error is coming, and the controller is not getting injected as I am not able to use those factory services. is this the correct method?
First of all you cannot inject controller to another controller, and One simple solution would be, instead of having each angular modules for each components, declare a module and add the factory service to controllers as dependency.
Code:
var app = angular.module('myApp', []);
app.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
app.controller('ControllerA', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
app.controller('ControllerB', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
Controllers are not injectable, because controller is not singleton. Controllers are constructor functions used to create instances of controllers. For example you can have multiple instances of one controller in your app:
angular.module('app', []);
angular
.module('app')
.controller('Example', function () {
this.x = Math.random();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="app">
First instance: <br>
<div ng-controller="Example as Ex1">
{{Ex1.x}}
</div>
Second instance: <br>
<div ng-controller="Example as Ex2">
{{Ex2.x}}
</div>
</div>
So if you want to share some behavior between controller you should use factory instead.
To inject a controller into another controller, use the $controller service.
app.controller('ControllerB', function($scope,$routeParams, $controller) {
var my = this;
$scope.ctrlA = $controller("ControllerA", {$scope: $scope});
});
The above example creates an instance of ControllerA as ctrlA with its $scope injected with the scope of the parent controller.
For more information, see AngularJS $controller Service API Reference.
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']);
I just started learning AngularJS and I am at a point of creating controllers and services ( factory ).
My folder structure is like the following:
Scripts
|
|-- Controllers
|
|-- invoiceController.js
|-- customerController.js
|
|-- Services
|
|-- invoiceServices.js
|-- customerServices.js
|
|-- app.js
Now I want to separate all the logics based on object ( eg Invoices, Customers, ... ).
So that I have a controller and service for my invoices, and one of both for my customers and so on.
But how do I inject the correct service in my controller?
When I try this:
app.js
(function () {
'use strict';
angular.module('skycountApp', [
invoiceService
]);
})();
invoiceController.js
(function () {
'use strict';
angular
.module('skycountApp')
.controller('InvoiceController', invoiceController);
invoiceController.$inject = ['$scope', 'Invoices'];
function homeController($scope, Invoices) {
$scope.text = Invoices;
}
})();
invoiceService.js
(function () {
'use strict';
var invoiceService = angular.module('invoiceService', ['ngResource']);
invoiceService.factory('Invoices', ['$resource',
function ($resource) {
return 'All invoices';
}
]);
})();
index.html
<!DOCTYPE html>
<html ng-app="skycountApp">
<head>
<meta charset="utf-8" />
<title>DOTA 2 Heroes</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-resource.js"></script>
<script src="app.js"></script>
</head>
<body ng-cloak>
<div ng-controller="InvoiceController">
<h1>{{text}}</h1>
</div>
</body>
</html>
I see the message All invoices.
But now I have injected the service in the app when it gets created. I will have more services ( one for customers, one for payments, ... ) so injecting them all in the beginning sounds silly to me.
How can I inject the correct service in the correct controller?
app.js
(function () {
'use strict';
angular.module('skycountApp', [
//invoiceService this is not needed here
]);
})();
invoiceController.js
(function () {
'use strict';
// Its only needed here, how to inject it??????
angular
.module('skycountApp')
.controller('InvoiceController', invoiceController);
invoiceController.$inject = ['$scope', 'Invoices'];
function homeController($scope, Invoices) {
$scope.text = Invoices;
}
})();
first of all why you are creating services on the the different angularjs module
(function () {
'use strict';
var invoiceService = angular.module('invoiceService', ['ngResource']);
invoiceService.factory('Invoices', ['$resource',
function ($resource) {
return 'All invoices';
}
]);
})();
simply create service on same angularjs module
(function () {
'use strict';
angular.module('skycountApp').factory('Invoices',['$resource',
function ($resource) {
return 'All invoices';
}
]);
})();
and then in your controller
(function () {
'use strict';
angular.module('skycountApp').controller('InvoiceController', function(Invoices){
$scope.text = Invoices;
})();
Note : include ngResource in app.js angular.module
Update : for using service define in other module you need to inject the module
(function () {
'use strict';
angular.module('skycountApp',['invoiceService']).controller('InvoiceController', function(Invoices){
$scope.text = Invoices;
})();
InvoiceController is a part of skycountApp module. It is coupled with it, and putting invoiceService into separate module doesn't make much sense. Doing
angular.module('skycountApp', ['invoiceService']);
means only that invoiceService was listed as a dependency for the module, and now the module has access to its components. Invoices service isn't injected and doesn't cause any overhead when InvoiceController isn't used.
If invoice and customer components will rarely be used by the same user, you can make invoiceService and InvoiceController a part of invoice module and use it only where it is needed (consider this module a separate app). But in the end you will most likely find that all js files have to be built into single bundle for the sake of performance.
I have a test module that set cookie isTesting to be true
app.controller('test_page',
['$scope', '$window', 'userService', 'flash', '$cookies',
function($scope, $window, userService, flash, $cookies) {
helper.initCommonScope($scope, $window, userService, flash)
$scope.refreshShownHidden = function() {
$scope.showTurnOffTest = $cookies.get('isTesting')
$scope.showTurnOnTest = ! $cookies.get('isTesting')
}
$scope.turnOnTest = function() {
$cookies.put('isTesting', true)
$scope.refreshShownHidden()
helper.turnOnTest()
}
$scope.turnOffTest = function() {
$cookies.put('isTesting', false)
$scope.refreshShownHidden()
helper.turnOffTest()
}
$scope.refreshShownHidden()
}])
And in helper.js, I have
exports.havePermission = function(access, resource, userService, entity) {
//Note: In debugging, we can grant client helper all access, and test robustness of server
if (angular.$cookies.isTesting)
return true
return permission.havePermission(access, resource, userService.isAuthenticated(), entity, userService.user)
}
But $cookies is not available since helper.js is not part of any angular module, thus no DI is available. How can I access the isTesting value?
I have tried using window.isTesting instead but it's not persisted when I refresh the page or go to other pages. So cookie is a better choice
You can use Angular's injector to access Angular modules and services outside of your Angular application.
AngularJS Code
angular.module('app', ['ngCookies']).
controller('ctrl', ['$cookies', function($cookies) {
$cookies.put('isTesting', true);
}]);
Non-Angular Code
helper = {
getCookies: function() {
// Create new injector for ngCookies module
var $injector = angular.injector(['ngCookies']);
// Inject $cookies to some function and invoke it
$injector.invoke(['$cookies', function($cookies) {
alert($cookies.get('isTesting'));
}]);
}
}
HTML
<html ng-app='app'>
<head>
<script data-require="angular.js#1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script data-require="angular-cookies.js#1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-cookies.js"></script>
<script src="script.js"></script>
<script src="helper.js"></script>
</head>
<body ng-controller="ctrl">
<button onclick="helper.getCookies()">Click Me</button>
</body>
</html>
Plunker: http://plnkr.co/edit/jur9A6d69ViiJqiFgopD?p=preview
var cookies = angular.injector(['ngCookies']).get('$cookies');
It creates a new instance of $cookies service, so if you're using it across the app, it is better to export it to global.
It's not the AngularJS purpose. You should try to keep all your stuff in your AngularJS code. However you can set any global variable in AngularJS:
app.controller('test_page',
['$scope', '$window', 'userService', 'flash', '$cookies',
function($scope, $window, userService, flash, $cookies) {
angular.$cookies = $cookies;
// or window.$cookies = $cookies;
helper.initCommonScope($scope, $window, userService, flash)
Then you can access $cookies anytime anywhere. It make certain things easier but less safe (any other script can access it too, it can create conflict, etc.)