Leonard Zakoor
asked on
How do I pass data to my factory properly using ngRoute and ngResource?
I'm new to Angular and still learning. I have an angular ecommerce app I'm building.
I have a category partial and a product partial. I'm using `ng-view` and `$routeProvider` for the navigation.
What I'm unable to figure out is how to pass this `PartNumber` to my product service factory in order to get the details. I'm not sure I setup the factory right.
Here's my controller:
Here's a link to the demo:
http://ur.430designs.com/quick-ship/#/category/
Click on a product to go to the product detail page
Any and all help is appreciated!
I have a category partial and a product partial. I'm using `ng-view` and `$routeProvider` for the navigation.
What I'm unable to figure out is how to pass this `PartNumber` to my product service factory in order to get the details. I'm not sure I setup the factory right.
Here's my controller:
var unarcoQS = angular.module('unarcoQS',['ngResource', 'ngCart', 'ngRoute', 'angular.filter']);
// Factories
unarcoQS.factory('categoryService', function ($resource) {
return $resource('http://example.com:7444/api/products/', {});
});
unarcoQS.factory('productService', function ($resource) {
return $resource('http://example.com:7444/api/products/:PartNumber',{PartNumber: "@PartNumber"});
});
unarcoQS.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider){
$routeProvider
.when('/',{
templateUrl:'template/home.html',
controller: "homeCtrl"
})
.when('/category/',{
templateUrl:'template/category.html',
controller: "catCtrl"
})
.when('/product/:PartNumber', {
templateUrl: 'template/product.html',
controller: ['$routeParams', function($routeParams) {
var self=this;
self.id = $routeParams;
return $routeParams;
}],
controllerAs: 'prodCtrl'
})
.otherwise({redirectTo:'/'});
// console.log($routeParams);
$locationProvider.html5Mode(false);
}]);
// Controllers
unarcoQS.controller ('homeCtrl', ['$scope', 'productService', 'ngCart', '$filter', function($scope, productService, ngCart) {
}]); //end homeCtrl
unarcoQS.controller ('catCtrl', ['$scope', 'categoryService', 'ngCart', '$filter', function($scope, categoryService, ngCart) {
ngCart.setTaxRate(7.5);
ngCart.setShipping(2.99);
var queryParams = {};
categoryService.query(queryParams, {}, function (response) {
$scope.products = response;
});
$scope.filtering = function(filter){
$scope.catFilter = filter;
// console.log(filter);
};
}]); //end catCtrl
unarcoQS.controller ('prodCtrl', ['$scope', 'productService', 'ngCart', '$route', '$routeParams', '$resource', function($scope, productService, ngCart, $route, $routeParams, $resource) {
id = $routeParams.PartNumber
$scope.product = productService.get({PartNumber: id});
console.log($scope.product);
}]); //end prodCtrl
Here's a link to the demo:
http://ur.430designs.com/quick-ship/#/category/
Click on a product to go to the product detail page
Any and all help is appreciated!
ASKER
Hi Julian,
I do kind of have that setup already on line 68. I did modify it per your suggestion.
If you go here: https://goo.gl/HT5rTE you can see it's throwing an error. It says:
TypeError: V is not a function
Is something with my service?
I do kind of have that setup already on line 68. I did modify it per your suggestion.
If you go here: https://goo.gl/HT5rTE you can see it's throwing an error. It says:
TypeError: V is not a function
Is something with my service?
I do kind of have that setup already on line 68Your code only goes up to line 65.
This sample should demonstrate the concept
Working sample here
<html ng-app="app">
<body>
<div class="wrapper" ng-controller="mainCtrl as ctrl">
<input ng-model="productId" type="text" placeholder="Product ID" />
<button class="btn btn-sm btn-primary" ng-click="ctrl.getProduct(productId)">Load</button>
<h2>Product Details</h2>
<div class="row">
<label class="col-md-2">{{ctrl.product.ProductName}}</label>
<div class="col-md-4"><span class="text-right">{{ctrl.product.price}}</span></div>
</div>
</div>
</body>
</html>
Angular<script>
(function() {
'use strict';
angular.module('app',['ngResource'])
.factory('productService', productService)
.controller('mainCtrl', mainController);
function productService($resource)
{
return $resource('t2237.service.php');
}
function mainController(productService)
{
var ctrl = this;
ctrl.getProduct = function(id) {
ctrl.product = productService.get({product: id});
};
}
})();
</script>
Working sample here
ASKER
Thanks for that Julian. Maybe I'm over complicating it. I'm still getting the V is not a function error.
Here's my current code that I was referring to:
Here's my current code that I was referring to:
unarcoQS.controller ('prodCtrl', ['$scope', 'productService', 'ngCart', '$route', '$routeParams', '$resource', function($scope, productService, ngCart, $route, $routeParams, $resource) {
var ctrl = this;
id = $routeParams.PartNumber
console.log(id);
ctrl.product = productService.get({PartNumber : id});
}]); //end prodCtrl
I have not figured out why yet but your parameter name PartNumber seems to be the culprit. Try changing factory to
This should get rid of the V is not a function bit but you still have a problem that a Resource GET expects a single object return and the GET in this case is returning an array - take a look at the results of this query
unarcoQS.factory('productService', function ($resource) {
return $resource('http://qsapi.unarcorack.com:7444/api/products/:PartNumber',{PartNumber: "@_PartNumber"});
});
And your invoke to$scope.product = productService.query({_PartNumber: id});
This should get rid of the V is not a function bit but you still have a problem that a Resource GET expects a single object return and the GET in this case is returning an array - take a look at the results of this query
http://qsapi.unarcorack.com:7444/api/products/PP-CN101-UNARCOYELLOW
You will see it is an array of objects not a single object.
ASKER
Thanks for that Julian. So is my factory wrong or my service? I didn't write the service so honestly I'm not sure why it's not doing that.
If I'm getting an array back, is there another way to show those results?
If I'm getting an array back, is there another way to show those results?
Yes you can do a query instead of a get - the query expects an array rather than a single record.
You will then also need to change your view (or controller) to either display all the records returned or (in the controller) select which one is relevant to show in the view
$scope.product = productService.query({_PartNumber: id});
You will then also need to change your view (or controller) to either display all the records returned or (in the controller) select which one is relevant to show in the view
ASKER
Hey Julian!
Thanks for that. Unfortunately I'm not getting that specific array back. Take a look here and look at the console. I'm doing
But in my console, I'm receiving about 160 records back. Is there something wrong with my controller?
I'm still new to Angular, but I do appreciate your time.
Thanks for that. Unfortunately I'm not getting that specific array back. Take a look here and look at the console. I'm doing
unarcoQS.controller ('prodCtrl', ['$scope', 'productService', 'ngCart', '$route', '$routeParams', '$resource', function($scope, productService, ngCart, $route, $routeParams, $resource) {
var ctrl = this;
id = $routeParams.PartNumber
$scope.product = productService.query({_PartNumber: id});
console.log($scope.product);
}]); //end prodCtrl
But in my console, I'm receiving about 160 records back. Is there something wrong with my controller?
I'm still new to Angular, but I do appreciate your time.
ASKER
That's what I'm seeing when I hit the API directly.
When I use my angular factory, I'm getting over 150 results. This is my first time using Angular services/factories, so I'm wondering if there's something wrong with how I've done my factory.
When I use my angular factory, I'm getting over 150 results. This is my first time using Angular services/factories, so I'm wondering if there's something wrong with how I've done my factory.
Please post your factory code and your controller code together. Since you made the change to _PartNumber you only posted the controller code.
The factory is simple - it just returns a Resource.
The resource takes a URL as a parameters that optionally specifies parameters to add to the URL - you use this if the URL requires a specific format for example
my.site.com/subfolder/:ID
You can submit parameters as part of the get / query that you don't specify in the URL component - these just get sent as GET or POST parameters and can be accessed as such on the other side.
In this case the API expects the PART NUMBER to be part of the URL - so in your factory you need to tell Resource how to create that url with the _Part_Number - if you don't get that part right the URL will not include the Part Number - but it will still work and the
.query({_PartNumber: 1}) will just submit the part number data as a GET request.
The factory is simple - it just returns a Resource.
The resource takes a URL as a parameters that optionally specifies parameters to add to the URL - you use this if the URL requires a specific format for example
my.site.com/subfolder/:ID
You can submit parameters as part of the get / query that you don't specify in the URL component - these just get sent as GET or POST parameters and can be accessed as such on the other side.
In this case the API expects the PART NUMBER to be part of the URL - so in your factory you need to tell Resource how to create that url with the _Part_Number - if you don't get that part right the URL will not include the Part Number - but it will still work and the
.query({_PartNumber: 1}) will just submit the part number data as a GET request.
ASKER
Sorry about that. Here's my entire controller.js file :
var unarcoQS = angular.module('unarcoQS',['ngResource', 'ngCart', 'ngRoute', 'angular.filter', 'ngPageTitle']);
// Factories
unarcoQS.factory('categoryService', function ($resource) {
return $resource('http://qsapi.unarcorack.com:7444/api/products/', {});
});
unarcoQS.factory('productService', function ($resource) {
return $resource('http://qsapi.unarcorack.com:7444/api/products/:PartNumber',{PartNumber: "@_PartNumber"});
});
unarcoQS.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider){
$routeProvider
.when('/',{
data: {
pageTitle: "Unarco Rack Quick Ship - Home"
},
templateUrl:'template/home.html',
controller: "homeCtrl"
})
.when('/category/',{
data: {
pageTitle: "Unarco Rack Quick Ship - Category"
},
templateUrl:'template/category.html',
controller: "catCtrl"
})
.when('/product/:PartNumber', {
data: {
pageTitle: "Unarco Rack Quick Ship - Product"
},
templateUrl: 'template/product.html',
controller: ['$routeParams', function($routeParams) {
var self=this;
self.id = $routeParams;
return $routeParams;
}],
controllerAs: 'prodCtrl'
})
.otherwise({redirectTo:'/'});
// console.log($routeParams);
$locationProvider.html5Mode(false);
}]);
// Controllers
unarcoQS.controller ('homeCtrl', ['$scope', 'productService', 'ngCart', '$filter', function($scope, productService, ngCart) {
}]); //end homeCtrl
unarcoQS.controller ('catCtrl', ['$scope', 'categoryService', 'ngCart', '$filter', function($scope, categoryService, ngCart) {
ngCart.setTaxRate(7.5);
ngCart.setShipping(2.99);
var queryParams = {};
categoryService.query(queryParams, {}, function (response) {
$scope.products = response;
});
$scope.filtering = function(filter){
$scope.catFilter = filter;
// console.log(filter);
};
}]); //end catCtrl
unarcoQS.controller ('prodCtrl', ['$scope', 'productService', 'ngCart', '$route', '$routeParams', '$resource', function($scope, productService, ngCart, $route, $routeParams, $resource) {
var ctrl = this;
id = $routeParams.PartNumber
$scope.products = productService.query({_PartNumber: id}, function(product){
$scope.product = product;
console.log(product);
});
}]); //end prodCtrl
Can you look in your console for this URL
http://qsapi.unarcorack.com:7444/api/products/PP-CN101-UNARCOYELLOW
It should be a GET - expand it, click the Response tab and paste a screen shot of that.
http://qsapi.unarcorack.com:7444/api/products/PP-CN101-UNARCOYELLOW
It should be a GET - expand it, click the Response tab and paste a screen shot of that.
ASKER
It is a GET Julian:
https://www.screencast.com/t/FEq5K1a49
https://www.screencast.com/t/FEq5K1a49
ASKER
Oh, I see what you were looking for. Sorry.
So I'm receiving the the correct response. Why isn't this what's being shown in my controller?
So I'm receiving the the correct response. Why isn't this what's being shown in my controller?
ASKER
Hey Julian,
One thing I noticed now is in the call it has a query string rather than a flat URL.
I need a call like this:
http://qsapi.unarcorack.com:7444/api/products/PP-CN101-UNARCOYELLOW
I'm getting this in the response:
http://qsapi.unarcorack.com:7444/api/products?_PartNumber=PP-CN101-UNARCOYELLOW
One thing I noticed now is in the call it has a query string rather than a flat URL.
I need a call like this:
http://qsapi.unarcorack.com:7444/api/products/PP-CN101-UNARCOYELLOW
I'm getting this in the response:
http://qsapi.unarcorack.com:7444/api/products?_PartNumber=PP-CN101-UNARCOYELLOW
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That was it! I had NO clue that ng resource and angular both had to be the same version. Thanks so much!!!
You are welcome.
Open in new window