AngularJS - Error: value.push is not a function - angularjs

I have a service defined like this ->
storegrServices.factory('productList', ['$resource', function($resource) {
return $resource('', {},{
query: {url:'/apis/productshome.php', method:'GET', isArray:false},
getProductDetail: {url:'/apis/getproductdetail.php', method:'POST', isArray:true}
});
}]);
And in the controller this is how I have called the POST ->
storegrControllers.controller('productPageCtrl', ['$scope','productList','$routeParams', function($scope, productList, $routeParams) {
$scope.postVariable = new productList();
$scope.postVariable.productcode = $routeParams.code;
$scope.postVariable.$getProductDetail();
}]);
This sends the product code to the server and the server returns with an array in the response. I have used isArray: true, however it still keeps giving me an error. I don't a 'value' variable/object in my code.
Please suggest how can I fix this.
This is the complete error that I get ->
Error: value.push is not a function
resourceFactory/</Resource[name]/promise</<#http://storegr.com/js-lib/angular-resource.js:530
q#http://storegr.com/js-lib/angular.min.js:7
resourceFactory/</Resource[name]/promise<#http://storegr.com/js-lib/angular-resource.js:529
yd/e/k.promise.then/w#http://storegr.com/js-lib/angular.min.js:92
yd/e/k.promise.then/w#http://storegr.com/js-lib/angular.min.js:92
yd/g/<.then/<#http://storegr.com/js-lib/angular.min.js:93
zd/this.$get</h.prototype.$eval#http://storegr.com/js-lib/angular.min.js:101
zd/this.$get</h.prototype.$digest#http://storegr.com/js-lib/angular.min.js:98
zd/this.$get</h.prototype.$apply#http://storegr.com/js-lib/angular.min.js:101
f#http://storegr.com/js-lib/angular.min.js:66
F#http://storegr.com/js-lib/angular.min.js:70
md/</B.onreadystatechange#http://storegr.com/js-lib/angular.min.js:71
http://storegr.com/js-lib/angular.min.js
Line 84
This is the response from the server ->
[{"sno":21,"cat1":"Beverages","cat1code":"B","cat2":"Carbonated Drinks&Fruit Drinks","cat2code":"CDD","cat3":"Fruit Juices","cat3code":"FJ","cumulative":20,"brand":"Real Juice","product":"Apple","productcode":"B-CDD-FJ-1","imagename":"B-CDD-FJ-1","weight":200,"unit":0,"mrp":20,"margin":0,"wsp":0,"vat":0,"hbprice":0,"discount":0,"availableqty":0,"availableprice":0,"existingqty":0,"existingprice":0,"addedqty":0,"addedprice":0,"soldqty":0,"soldprice":0,"tags":"home"}]

I was able to work this around, answering it here so that it could benefit some one else too.
I modified my array response to be a json object like this and it worked.
{ "product":
[{"sno":21,"cat1":"Beverages","cat1code":"B","cat2":"Carbonated Drinks&Fruit Drinks","cat2code":"CDD","cat3":"Fruit Juices","cat3code":"FJ","cumulative":20,"brand":"Real Juice","product":"Apple","productcode":"B-CDD-FJ-1","imagename":"B-CDD-FJ-1","weight":200,"unit":0,"mrp":20,"margin":0,"wsp":0,"vat":0,"hbprice":0,"discount":0,"availableqty":0,"availableprice":0,"existingqty":0,"existingprice":0,"addedqty":0,"addedprice":0,"soldqty":0,"soldprice":0,"tags":"home"}]
}
Thank you.

Related

How to create a POST request in my case?

I am trying to make a POST request via $resource object in Angular.
I have something like
(function (angular) {
angular.module('myApp')
.factory('myService', [
'$resource',
function ($resource) {
var serviceObj = $resource('http://testProject/products/', {id: '#id'},{
'createItem' : {
url: 'http://testProject/item/:id',
method: 'POST',
params: {type: ‘#type'}
}
});
return serviceObj;
}
]);
})(angular);
in my controller
//omit the controller codes…
myService.type = ‘Detail’;
myService.createItem(function(data) {
console.log(data)
});
I see stuff back from the console.log but it has the wrong data because the type is shown as ‘Name’ instead of ‘Detail’. I know api supports that and I don’t see anything wrong with my service. Can someone help me out for it? Thanks a lot!
It looks like your are getting data back,
I would try:
console.log(data.data);
Since your are returning an object from your service.

AngularJS $resource service's $save() POSTs to incorrect route

I have a basic factory returning a $resource called User:
angular.module('appServices').factory('User', [
'$resource',
function($resource){
return $resource('http://localhost:3000/users/:username', {username:'#username'});
}]);
In my UserController.js file I try to do something fairly simple:
angular.module("myApp").controller('UserController', ['$scope', '$routeParams', 'User',
function($scope, $routeParams, User){
var user = new User({email:'user#example.com', username: 'johndoe', password: 'mySecurePassw0rd!'});
user.$save();
}]);
I expect the $save() function to make a POST request to /users, however in the console I get http://localhost:3000/users/johndoe 404 response, because the route is obviously not set up on the server for POST requests with the username parameter appended...
Why is it that it does so in my code sample ? From the examples I have seen on the internet, the $save() function does not take into account the username and should directly POST to /users in my case.
Any help would be appreciated!
EDIT
I think I got the error (as always, immediately after posting the question on SO...)
It is probably because of the default parameter {username: "#username"} I specified in the $resource, as it expects there to be a username parameter by default ?
So the correct way to do it would be to return this resource from the factory:
return $resource('http://localhost:3000/users/:username');
correct ?
Username is a natural primary key. Unless you use switch to a surrogate one (generated on server side), you will need two different methods for entity creating and updating:
var User = $resource(
'/users/:username',
{
username: '#username'
},
{
save: {
methods: 'POST',
url: '/users'
},
update: {
method: 'PUT'
}
}
);

Angularjs $resource, how do I know which obj is being passed to it? URL not receiving :id

I am using a MEAN stack and I am a little confused on how the $resource works. I understand that the $resource factory is a service that retrieves data for controllers. However, I have two model objects, Compositions and Critiques. What I am trying to do is get critiques based off the url, which looks something like this: /compositions/:compositionId/review.
For some reason whenever I call
Reviews.query(function(review) {
console.log(review);
$scope.reviews= review;
});
I get this error:
GET localhost:3000/compositions/review 500 (Internal Server Error)
Here are my services:
angular.module('mean').factory('Reviews', ['$resource',
function($resource) {
return $resource('compositions/:docId/review', {
docId: '#docId'
},
{
update: {
method: 'PUT'
}
});
}
]);
angular.module('mean').factory('Compositions', ['$resource',
function($resource) {
return $resource('compositions/:compositionId', {
compositionId: '#_id'
},
{
update: {
method: 'PUT'
}
});
}
]);
The second one works if I navigate to /compositions/:compId, but the first one does not. Instead I get the error above. Why isn't the docId being passed in? Any ideas?
I want the compositionId, which is the docId in the 'critique' object models terms, but I want to get back critique objects. What am I doing wrong? Any help or advice is appreciated, thanks!
You are passing callback to query() - that is wrong. You should pass there a params object with your docId. This is how you should do that (in Angular 1.2)
Reviews.query({docId: 5}).$promise.then(function(review) {
console.log(review);
});

angular.js and untappd API, how to send a Get request

I'm trying to connect to Untappd API trought angular.js; the API docs says
Whenever you are making a call to the API, you MUST pass both your Client ID and Client Secret as GET params like below
http://api.untappd.com/v4/method_name?client_id=CLIENTID&client_secret=CLIENTSECRET
with angular I have done this simply controller
function UntappdController($scope,$http) {
$http.get('http://api.untappd.com/v4/user/badges/jonnyjava?client_id=XXX&client_secret=XXX').success(function(data) {
alert('ok');
}).
error(function(data, status, headers, config) {
alert('ko');
});
}
UntappdController.$inject = ['$scope', '$http'];
but it doesn't work. (I get always KO)
So I'have tried tro a RESTful service. In this way
angular.module('BadgeServices', ['ngResource']).
factory('Badge', function($resource){
return $resource('http://api.untappd.com/v4/user/badges/jonnyjava/', {}, {
query: {method:'GET',params:{client_id: 'XXX', client_secret: 'XXX'}, isArray:true}
});
});
But this doesn't works too...
What I'm doing wrong? I'm new to angular. It looks simple but I'm missing something fundamental...
The error function is passed these variables: data, status, headers, config. Check their contents - I'm sure the server has some why of specifying what went wrong.
Sorry, I forgot it! Here is what I get with the error function..
data: status:0 headers:function (name) {
"use strict";
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
return headersObj[lowercase(name)] || null;
}
return headersObj;
}config:[object Object]
Nothing helpful...
Solved! It was a CORS problem. If anyone is interest the solutions is here.
stackoverflow-Angularjs issue $http.get not working

query string in $resource url

my service has to use a query string due to limitations on the server that runs classic ASP:
angular
.module('myServices', ['ng', 'ngResource'])
.factory('Item', ['$resource',
function ($resource) {
return $resource('/api/?p=item/:id');
}]);
and I want to add extra query string parameters to it:
Item.query({test: 123}, on_success, on_error);
but the resulting url is
/api/?p=item?test=123
apparently there is a bug, but how to get around it?
EDIT: filed this at https://github.com/angular/angular.js/issues/1511
You can use resource parameters. If you haven't specified placeholders in the path, they would automatically be converted into query string params. Like that:
angular
.module('myServices', ['ng', 'ngResource'])
.factory('Item', [
'$resource',
function ($resource) {
return $resource('/api');
}]);
Item.query({p: 'item/1'});
This would result in a request to /api?p=item/1.
P.S.
I suppose you already know that, but you don't like it. But I still think this is the correct way in your case. Considering the bad API design you are dealing with that back-end you could wrap the AngularJS resources with another service which does this for you.
var deferred = $q.defer();
api.api_name.query({
'param':param_value
},
function(response) {
deferred.resolve(response);
},
function(response) {
deferred.reject(response);
}
);
//
angular
.module('module_name')
.factory('api',function($resource){
var api_var={};
api_var.api_name = $resource('url?param_key=:param', {
param: '#param'
}, {
'query': {
method: 'get'
}
});
return api_var;
});

Resources