I have the following error on my APP
Error: [$injector:unpr] http://errors.angularjs.org/1.3.2/$injector/unpr?p0=ProductResourceProvider%20%3C-%20ProductResource
My Scenario is as follows, a simple app that gets info from a webservice, but with ng mock I want to load the products if the webservice is not implemented.
In my head tag I used the code like this:
<script src="//code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js" type="text/javascript"></script>
<script src="//code.angularjs.org/1.3.2/angular-resource.min.js" type="text/javascript"></script>
<script src="//code.angularjs.org/1.3.2/angular-mocks.js" type="text/javascript"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.2.js"c></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>|
<!-- Application Script -->
<script src="../Scripts/App/App.js" type="text/javascript"></script>
<!-- Services -->
<script src="../Scripts/App/Common/Services/common.services.js" type="text/javascript"></script>
<script src="../Scripts/App/Common/Services/productResource.js"></script>
<script src="../Scripts/App/Common/Services/productResourceMock.js" type="text/javascript"s></script>
<!--Controllers -->
<script src="../Scripts/App/Products/ProductListCtrl.js" type="text/javascript"></script>
My App.Js defines the module and its dependencies:
(function () {
"use strict";
var app = angular.module("productManagement", ["common.services", "productResourceMock"]);
}());
The Product Controller, very simple:
(function () {
"use strict";
angular
.module("productManagement")
.controller("ProductListCtrl",
["ProductResource",
ProductListCtrl]);
function ProductListCtrl(productResource) {
var vm = this;
productResource.query(function (data) {
vm.products = data;
});
vm.showImage = false;
vm.toggleImage = function () {
vm.showImage = !vm.showImage;
}
}
}());
The Common.Services (which has ng-resource)
(function () {
"use strict";
angular
.module("common.services",
["ngResource"])
}());
Then product resource
(function () {
"use strict";
angular
.module("common.services")
.factory("productResource",
["$resource",
productResource]);
function productResource($resource) {
return $resource("/api/products/:productId")
}
}());
and finally product resource mock
(function () {
"use strict";
var app = angular
.module("productResourceMock",
["ngMockE2E"]);
app.run(function ($httpBackend) {
var products = [
{
"productId": 1,
"productName": "Leaf Rake",
"productCode": "GDN-0011",
"releaseDate": "March 19, 2009",
"description": "Leaf rake with 48-inch wooden handle.",
"cost": 9.00,
"price": 19.95,
"category": "garden",
"tags": ["leaf", "tool"],
"imageUrl": "http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png"
},
{
"productId": 2,
"productName": "Garden Cart",
"productCode": "GDN-0023",
"releaseDate": "March 18, 2010",
"description": "15 gallon capacity rolling garden cart",
"cost": 20.00,
"price": 32.99,
"category": "garden",
"tags": ["barrow", "cart", "wheelbarrow"],
"imageUrl": "http://openclipart.org/image/300px/svg_to_png/58471/garden_cart.png"
},
{
"productId": 5,
"productName": "Hammer",
"productCode": "TBX-0048",
"releaseDate": "May 21, 2013",
"description": "Curved claw steel hammer",
"cost": 1.00,
"price": 8.99,
"category": "toolbox",
"tags": ["tool"],
"imageUrl": "http://openclipart.org/image/300px/svg_to_png/73/rejon_Hammer.png"
},
{
"productId": 8,
"productName": "Saw",
"productCode": "TBX-0022",
"releaseDate": "May 15, 2009",
"description": "15-inch steel blade hand saw",
"cost": 6.95,
"price": 11.55,
"category": "garden",
"tags": ["garden", "mower"],
"imageUrl": "http://openclipart.org/image/300px/svg_to_png/27070/egore911_saw.png"
},
{
"productId": 10,
"productName": "Video Game Controller",
"productCode": "GMG-0042",
"releaseDate": "October 15, 2002",
"description": "Standard two-button video game controller",
"cost": 2.22,
"price": 35.95,
"category": "gaming",
"tags": ["gaming", "controller", "video game"],
"imageUrl": "http://openclipart.org/image/300px/svg_to_png/120337/xbox-controller_01.png"
}
];
var productUrl = "/api/products"
$httpBackend.whenGET(productUrl).respond(products);
var editingRegex = new RegExp(productUrl + "/[0-9][0-9]*", '');
$httpBackend.whenGET(editingRegex).respond(function (method, url, data) {
var product = {"productId": 0};
var parameters = url.split('/');
var length = parameters.length;
var id = parameters[length - 1];
if (id > 0) {
for (var i = 0; i < products.length; i++) {
if (products[i].productId == id) {
product = products[i];
break;
}
};
}
return [200, product, {}];
});
$httpBackend.whenPOST(productUrl).respond(function (method, url, data) {
var product = angular.fromJson(data);
if (!product.productId) {
// new product Id
product.productId = products[products.length - 1].productId + 1;
products.push(product);
}
else {
// Updated product
for (var i = 0; i < products.length; i++) {
if (products[i].productId == product.productId) {
products[i] = product;
break;
}
};
}
return [200, product, {}];
});
// Pass through any requests for application files
$httpBackend.whenGET(/app/).passThrough();
})
}());
I checked the spelling and found nothing yet, so I am sure what I am missing here
and before I forget the rest of the html
<div ng-app="productManagement" class="container">
<div class="panel panel-primary">
<div class="panel-heading"
style="font-size:large">Product
List
</div>
<div class="panel-body">
<table class="table" ng-controller="ProductListCtrl as vm">
<thead>
<tr>
<td>
<button type="button"
class="btn btn-primary"
ng-click="vm.toggleImage()">
{{vm.showImage ? "Hide" : "Show"}} Image
</button>
</td>
<td>Product</td>
<td>Code</td>
<td>Available</td>
<td>Price</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in vm.products">
<td>
<img ng-if="vm.showImage"
ng-src="{{product.imageUrl}}"
style="width:50px;margin:2px"
title="{{product.productName}}">
</td>
<td>{{ product.productName}}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate }}</td>
<td>{{ product.price | currency }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Spelling is off here - the ProductResource-factory is defined as .factory("productResource") with lowercase p: