Trying to get simple Angular DI working in an existing ASP.NET 5 (Core) project.
Been following this tutorial.
Versions:
AngularJS 1.4.6
ASP.NET 5 (vNext)
Visual Studio 2015
Windows 10
Checked all the basic gotchas with naming and so on. Unclear about how my dependent js-files "controllers.js" & "services.js" are suppose to be discovered by Angular?
If I explicitly include them - which by the tutorial shouldn't be required - I still get
[ng:areq] Argument 'customerController' is not a function, got
undefined
Index.html
<!DOCTYPE html>
<html ng-app="bonusapp">
<head>
<meta charset="utf-8" />
<link href="lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="lib/bootswatch/yeti/bootstrap.min.css" rel="stylesheet" />
<link href="css/main.css" rel="stylesheet" />
<script type="text/javascript" src="lib/angular/angular.js"></script>
<script type="text/javascript" src="lib/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="lib/angular-route/angular-route.js"></script>
<script src="lib/app.js"></script>
<!--<script>angular.bootstrap(document, ['app']);</script>-->
</head>
<body ng-cloak>
<div id="wrapper" ng-controller="customerController">
<div id="main" class="container-fluid">
<div class="row">
<div class="col-md-3">
<h2>Kunder</h2>
<ul>
<li ng-repeat="item in Models">
{{item.FirstName}} {{item.LastName}} <a>Redigera</a> <a>Radera</a>
</li>
</ul>
</div>
</div>
</div>
<script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/jquery-validation/dist/jquery.validate.js"></script>
<script type="text/javascript" src="lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</body>
</html>
app.js
(function () {
'use strict';
// Define module "app"
angular.module('bonusapp', [
// Angular modules
'ngRoute',
'ngResource',
// Custom modules
'customerService'
// 3rd Party Modules
]);
})();
controllers.js
(function () {
'use strict';
// Assign controller to app
angular
.module('bonusapp')
.controller('customerController', [
customerController]);
// $inject() method call is required to enable the controller to work with minification.
customerController.$inject = [
'$scope',
'Customers'
];
// Construct controller
function customerController($scope, Customers) {
// Populate model from service
$scope.Models = Customers.get();
}
})();
services.js
(function() {
'use strict';
var customerService =
angular
.module('customerService', ['ngResource']);
customerService
.factory('Customers',
['$resource'],
function ($resource) {
return $resource('/api/customers', {}, {
// Service call to get Customers
get: {
method: 'GET',
params: {},
isArray: true
}
});
}
);
})();
As Win suggested, I needed to:
Fix the include order to put jQuery first
Include all my JS files
But I still had some issues. For reference, here are the fixed scripts:
controller.js
(function () {
'use strict';
// Construct controller
// Remarks: controller is now declared FIRST
var customerController = function ($scope, Customers) {
$scope.Title = "Title";
// Populate model from service
$scope.Models = Customers.get();
}
// $inject() method call is required to enable the controller to work with minification.
customerController.$inject = [
'$scope',
'Customers'
];
// Assign controller to app
angular
.module('bonusapp')
.controller('customerController',
customerController);
})();
services.js
(function() {
'use strict';
var customerService =
angular
.module('customerService',
['ngResource']);
customerService
.factory('Customers',
['$resource',
function ($resource) {
return $resource('/api/customers', {}, {
// Service call to get Customers
// Remarks: 'get' in single quotes
'get': {
method: 'GET',
params: {},
isArray: true
}
});
}
]);
})();
You need to include controller.js and services.js files.
In addition, you need to move jquery before angular.js.
<script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="lib/angular/angular.js"></script>
<script type="text/javascript" src="lib/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="lib/angular-route/angular-route.js"></script>
<script src="lib/app.js"></script>
<script src="lib/controllers.js"></script>
<script src="lib/services.js"></script>
FYI: You might also want to look into bundling and magnification, before you publish.
ngResource in factory works fine but unfortunately the result able to select JSON index. At the same time it is possible to bind the same $scope.resultItems variable
Console log appear like this 👇
Not working from ngResource http://codepen.io/anon/pen/dMbRXx
Working fine from variable http://codepen.io/anon/pen/ONLgNX
var app = angular.module('app', ['ngResource']);
app.controller('myCtrl', function($scope, categoryFilter) {
$scope.resultItems = categoryFilter.query();
$scope.resultIndex = $scope.resultItems[0];
$scope.resultIndexItem = $scope.resultItems[0].status;
});
app.factory('categoryFilter', function($resource) {
return $resource("https://maps.googleapis.com/maps/api/geocode/json?address=NY", {}, {
query: {
method: "GET"
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-resource/1.5.0/angular-resource.min.js"></script>
<div class="container" ng-app="app" ng-controller="myCtrl">
<div class="col-xs-12">
<h3>ngResource result</h3>
<pre>{{resultItems | json }}</pre>
<hr />
<pre>{{resultIndex | json }}</pre>
<hr />
<pre>{{resultIndexItem | json}}</pre>
</div>
</div>
Each resource in fact is a ajax request that means it is asynchronous, So you have to use callbacks to query function. Then your code looks like this
var app = angular.module('app', ['ngResource']);
app.controller('myCtrl', function($scope, categoryFilter) {
categoryFilter.query(function(results){
$scope.resultItems = results;
$scope.resultItems.results[0];
$scope.resultIndexItem = $scope.resultItems.status;
});
});
app.factory('categoryFilter', function($resource) {
return $resource("https://maps.googleapis.com/maps/api/geocode/json?address=NY", {}, {
query: {
method: "GET"
}
});
});
link
Update
Sorry If I miss read you question, All items in json within {} will be an object can be accessed using ., For example in json results and status is object and items represented in [] is an array and they can be accessed using index.
From json
I am new in angular js, now I am trying to use factory to make code clearer. But now I am getting the following error:
$injector:unpr(Unknown provider).
I stuck here and cant find where is the problem. Service and this controller were in different files actually, then I tried to put them together, but still it doesnt work. I will be very glad if you will help me to find out my problem.
var app = angular.module('myApp', ['ngRoute']);
app.factory('AuthenticationService', ['$scope', '$location', function($scope, $location){
var currentUser;
return {
login: function(username, password){
var endPoint = "http://localhost:8080/RestServer/main/just/Authorize";
var jsonData = {
username: username,
password: password
};
var jsonString = JSON.stringify(jsonData);
$http.post(endPoint, jsonString,{headers: {'Content-Type': 'application/json'}}).success(function (data,status, headers ){
if(data.access == "ok")
{
$location.path("learning");
}
else
{
$location.path("error");
}
});
},
logout: function(){},
isLoggedIn: function(){},
curUser: function(){return currentUser}
};
}
]);
app.controller('loginController',['$scope', 'AuthenticationService', function($scope, AuthenticationService)
{
$scope.login = function()
{
AuthenticationService.login($scope.username, $scope.password);
}
}]);
Here is html:
<html data-ng-app="myApp">
<head>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular-route.min.js"></script>
<script src="Scripts/app.js"></script>
<script src="Scripts/services.js"></script>
<script src="Scripts/controllers.js"></script>
<link href="CSS/bootstrap.min.css" rel="stylesheet">
<title>Welcome!</title>
</head>
<body>
<div class="container theme-showcase" role="main" ng-view="">
</div>
</body>
Just remove $scope from your factory, You don't typically use $scope inside a factory, service or provider,also add $http as a dependency since you are making a $http call
app.factory('AuthenticationService', [ '$location','$http', function( $location,$http){
}
Here is the working Application
I'm trying to build my own service by following the example in the documentation for the factory methodology. I think I've done something wrong however because I continue to get the unknown provider error. This is my code for my app including the declaration, configuration and factory definition.
EDIT
I've now added all of the files to help troubleshoot
EDIT
The full details of the error are below the issues appears to be with getSettings, as it's looking for getSettingsProvider and cannot find it
Error: [$injector:unpr] http://errors.angularjs.org/1.2.16/$injector/unpr? p0=getSettingsProvider%20%3C-%20getSettings
at Error (native)
at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:6:450
at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:35:431
at Object.c [as get] (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:13)
at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:35:499
at c (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:13)
at d (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:230)
at Object.instantiate (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:394)
at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:66:112
at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:53:14 angular.js:9778
(anonymous function) angular.js:9778
(anonymous function) angular.js:7216
h.$apply angular.js:12512
(anonymous function) angular.js:1382
d angular.js:3869
$b.c angular.js:1380
$b angular.js:1394
Wc angular.js:1307
(anonymous function) angular.js:21459
a angular.js:2509
(anonymous function) angular.js:2780
q angular.js:330
c
These are all of the files I have in my app currently
app.JS
//Initialize angular module include route dependencies
var app = angular.module("selfservice", ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl:"partials/login.html",
controller:"login"
});
});
app.factory('getSettings', ['$http', '$q', function($http, $q) {
return function (type) {
var q = $q.defer();
$http.get('models/settings.json').success(function (data) {
q.resolve(function() {
var settings = jQuery.parseJSON(data);
return settings[type];
});
});
return q.promise;
};
}]);
And here is how I am using this service in my controller
controller.JS
app.controller("globalControl", ['$scope','getSettings', function ($scope,getSettings) {
var loadSettings = getSettings('global');
loadSettings.then(function(val) {
$scope.settings = val;
});
}]);
app.controller("login", ['$scope', function ($scope) {
return ""
}]);
directives.js
app.directive('watchResize', function(){
return {
restrict: 'M',
link: function(scope, elem, attr) {
scope.spacer = (window.innerWidth < 1025) ? '' : 'large-3';
scope.button = (window.innerWidth < 1025) ? '' : 'large-6';
angular.element(window).on('resize', function(){
scope.$apply(function(){
scope.spacer = (window.innerWidth < 1025) ? '' : 'large-3';
scope.button = (window.innerWidth < 1025) ? '' : 'large-6';
});
});
}
};
});
And if it's pertinent here's the HTML
<html class="no-js" lang="en" ng-app="selfservice" ng-controller="globalControl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{settings.title}}</title>
<link rel="stylesheet" href="css/app.css" />
<script src="bower_components/modernizr/modernizr.js"></script>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
</head>
<body>
<div id="template">
<header id="header">
<img src="{{settings.logo}}" alt="{{settings.logoDescription}}"/>
</header>
<div id="view">
<ng-view></ng-view>
</div>
</div>
<script src="bower_components/foundation/js/foundation.min.js"></script>
<script>
//initialize foundation
$(document).foundation();
</script>
</body>
</html>
Can someone point me in the right direction? I have done my best to follow the documentation, and looking through SO most of the related issues are much more in depth, and more difficult for me to understand. This is my first time creating a service.
also one of the popular reasons maybe you miss to include the service file in your page
<script src="myservice.js"></script>
Your angular module needs to be initialized properly. The global object app needs to be defined and initialized correctly to inject the service.
Please see below sample code for reference:
app.js
var app = angular.module('SampleApp',['ngRoute']); //You can inject the dependencies within the square bracket
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl:"partials/login.html",
controller:"login"
});
$locationProvider
.html5Mode(true);
}]);
app.factory('getSettings', ['$http', '$q', function($http, $q) {
return {
//Code edited to create a function as when you require service it returns object by default so you can't return function directly. That's what understand...
getSetting: function (type) {
var q = $q.defer();
$http.get('models/settings.json').success(function (data) {
q.resolve(function() {
var settings = jQuery.parseJSON(data);
return settings[type];
});
});
return q.promise;
}
}
}]);
app.controller("globalControl", ['$scope','getSettings', function ($scope,getSettings) {
//Modified the function call for updated service
var loadSettings = getSettings.getSetting('global');
loadSettings.then(function(val) {
$scope.settings = val;
});
}]);
Sample HTML code should be like this:
<!DOCTYPE html>
<html>
<head lang="en">
<title>Sample Application</title>
</head>
<body ng-app="SampleApp" ng-controller="globalControl">
<div>
Your UI elements go here
</div>
<script src="app.js"></script>
</body>
</html>
Please note that the controller is not binding to an HTML tag but to the body tag. Also, please try to include your custom scripts at end of the HTML page as this is a standard practice to follow for performance reasons.
I hope this will solve your basic injection issue.
app.factory('getSettings', ['$http','$q' /*here!!!*/,function($http, $q) {
you need to declare ALL your dependencies OR none and you forgot to declare $q .
edit:
controller.js : login, dont return ""
This error is also appears when one accidntally injects $scope into theirs factory:
angular.module('m', [])
.factory('util', function ($scope) { // <-- this '$scope' gives 'Unknown provider' when one attempts to inject 'util'
// ...
});
Spent a few hours trying to solve the same. This is how I did it:
app.js:
var myApp = angular.module( 'myApp', ['ngRoute', 'ngResource', 'CustomServices'] );
CustomServices is a new module I created and placed in a separate file called services.js
_Layout.cshtml:
<script src="~/Scripts/app.js"></script>
<script src="~/Scripts/services/services.js"></script>
services.js:
var app = angular.module('CustomServices', []);
app.factory( 'GetPeopleList', ['$http', '$log','$q', function ( $http, $log, $q )
{
//Your code here
}
app.js
myApp.controller( 'mainController', ['$scope', '$http', '$route', '$routeParams', '$location', 'GetPeopleList', function ( $scope, $http, $route, $routeParams, $location, GetPeopleList )
You have to bind your service to your new module in the services.js file AND of course you have to use that new module in the creation of your main app module (app.js) AND also declare the use of the service in the controller you want to use it in.
I was getting this problem and it turned out I had included my controller both in ui.router and in the html template as in
.config(['$stateProvider',
function($stateProvider) {
$stateProvider.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard/views/index.html',
controller: 'DashboardController'
});
}
]);
and
<section data-ng-controller="DashboardController">
Please "include" both Controller and the module(s) where the controller and the functions called in the Controller are.
module(theModule);
# user2310334
I just tried this, a VERY basic example:
HTML file
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-route.min.js" type="text/javascript"></script>
<script src="./app.js" type="text/javascript"></script>
</head>
<body>
<div ng-controller="MailDetailCtrl">
</div>
</body>
</html>
The javascript file:
var myApp= angular.module('app', ['ngRoute']);
myApp.factory('mailService' , function () {
return {
getData : function(){
var employees = [{name: 'John Doe', id: '1'},
{name: 'Mary Homes', id: '2'},
{name: 'Chris Karl', id: '3'}
];
return employees;
}
};
});
myApp.controller('MailDetailCtrl',['$scope', 'mailService', function($scope, mailService) {
alert(mailService.getData()[0].name);
}]);
And it works. Try it.
Be sure that you load controller outsideapp.config. The following code may cause this error:
app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
var AuthCtrl = require('components/auth/AuthCtrl'); //NOTICE HERE
$stateProvider.state('login',{
url: "/users/login",
templateUrl: require("components/auth/login.tpl.html"),
controller: AuthCtrl // ERROR
})
}))
To fix this error, we must move AuthCtrl to outsideapp.config:
var AuthCtrl = require('components/auth/AuthCtrl'); //NOTICE HERE
app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('login',{
url: "/users/login",
templateUrl: require("components/auth/login.tpl.html"),
controller: AuthCtrl // WORK
});
}))
In my case, I added a new service (file) to my app. That new service is injected in an existing controller. I did not miss new service dependency injection into that existing controller and did not declare my app module no more than one place. The same exception is thrown when I re-run my web app and my browser cache is not reset with a new service file codes. I simply refreshed my browser to get that new service file for browser cache, and the problem was gone.
Since this is the first Stackoverflow question that appears on Google when searching for Error: $injector:unpr Unknown Provider I'll add this here.
Make sure that in your index.html any modules/dependencies are not being loaded after they are needed.
For example in my code customFactory.factory.js begins like this:
angular
.module("app.module1")
.factory("customFactory", customFactory);
However the index.html looked like this:
<script src="/src/client/app/customFactory.factory.js"></script>
<script src="/src/client/app/module1.module.js"></script>
Where it should've really looked like this:
<script src="/src/client/app/module1.module.js"></script>
<script src="/src/client/app/customFactory.factory.js"></script>
Since customFactory.factory.js is declared as part of module1, it needs to be loaded before customFactory
I got this error writing a Jasmine unit test. I had the line:
angular.injector(['myModule'])
It needed to be:
angular.injector(['ng', 'myModule'])
When you are using ui-router, you should not use ng-controller anywhere. Your controllers are automatically instantiated for a ui-view when their appropriate states are activated.
I am getting this error and I tried different methods, but still I have not found any solution.
This is my code:
services.js
angular
.module('myApp.services',[])
.service('myservice', function($resource) {
var pendings = $resource('myUrl2', {methode: 'GET', isArray:true});
var items;
var myPo='rawad al bo3bo3';
var quantity;
var barcode;
return {
getItems: function() {
items = $resource('myUrl', {methode: 'GET', isArray:true});
And this is my controllers:
angular
.module('myApp.controllers', [])
.controller('ReceiveCtrl', ['$scope','myservice', function ($scope,myservice) {
html:
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<!-- <link rel="stylesheet" href="lib/primeUI/prime-ui-0.9.5.css"> -->
</head>
<body>
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view></div>
</body>
</html>
In the controller I can't access the variable coming from my services... so the alert message won't work and I get this error
Error: Unknown provider: $resourceProvider <- $resource <- myservice
You have to include angular-resource.js file and load ngResource module: angular.module('app', ['ngResource'])
For more details check "Installation" section inside the documentation for the $resource service: http://docs.angularjs.org/api/ngResource.$resource
The service module also require the resource.
angular.module('myApp.services',[])
should be
angular.module('myApp.services',['ngResource'])
and also the controller needs to know about your service-module
angular.module('myApp.controllers', [])
to
angular.module('myApp.controllers', ['myApp.services','myApp.filters', 'myApp.directives'])
and techincally, your motherModule does not require myApp.services only the myApp.controllers
angular.module('myApp', ['myApp.services','myApp.filters', 'myApp.directives' 'myApp.controllers']).
to
angular.module('myApp', ['myApp.controllers']).