Angular-resource query error - angularjs

I'm receiving the following error from $resource:
Error: [$resource:badcfg] Error in resource configuration for action `query`. Expected response to contain an array but got an object
the API is not returning an Array but it return this:
{
list: [...items...],
next: true,
limit: 100,
last: 0
}
I need to get the entire object with query() and push list in my $scope.items.
The other params needs for pagination or infinite scroll.
How can I do that?
EDIT:
This is my factory:
angular.module('app').factory('Items', ['$resource',
function ($resource) {
return $resource('/items/:id', { id: '#id' }, {
'query': {
method: 'GET',
isArray: false
},
update: {
method: 'PUT'
}
});
}
]);

Your factory is right, just remove single quotes from query:
...
query: {
method: 'GET',
isArray: false
}
...
EDIT after below comment
I had exactly the same problem few days ago, which was solved by setting isArray to true. So I quite confident in syntax, but for me I have slightly different declaration of factory:
angular.module('docAccessApp',[]).factory('Access',function($resource){
return $resource('http://localhost:8080/documentAccesses/:id',{id:'#_id'},{
query: {
method: 'GET',
isArray:false
}
});
});
Maybe you need to Hard Reload the page so that browser refreshes all the js cache.

Related

Firebase request: Error in resource configuration for action `array`. Expected response to contain an object but got an GET

I found lots of posts on this issue and tried to implement some of the solutions proposed here:
But it still does not work and I am wondering if using firebase could be an issue. I have created a service linking to my Firebase datasource:
servicesModule.factory("postsDB", function($resource){
return $resource("https://<datasource>.firebaseio.com/Posts/:id", {
id: "#id"
},
{
update: {
method: "PUT",
isArray : true
}
});
});
Then my controller:
controllersModule.controller('BlogCtrl', ["$scope", "postsDB", function($scope, postsDB) {
postsDB.query(function(posts){
$scope.myPosts = posts;
})
}]);
The ng-repeat result:
<div class="col s12 m6" id="postItems" ng-repeat="post in myPosts">
<h3>{{post.Title}}</h3>
{{post.Body}}
{{post.Author}}
</div>
I really do not understand what:
Error: $resource:badcfg
Response does not match configured parameter
means (as usual with angular errors) except that it is obviously expecting an array and I though that the whole point of using postsDB.query was to do just that. I have added isArray: true above but it has no effect whatsoever. Why aren't my posts being loaded if the resource exists as a JSON posts array?
Couple things: you need to append .json to the path to use Firebase's REST API and second, you'll need to set isArray: false specifically for the query method.
servicesModule.factory("postsDB", function($resource) {
return $resource("https://<datasource>.firebaseio.com/Posts/:id.json", {
id: "#id"
},
{
update: {
method: "PUT",
isArray: true
},
query: {
method: "GET",
isArray: true
}
});
});

Building one object with only one $resource

I'm building a fullrest app with $resources, I read about It but I didn't find any answer.
return $resource('/rings', {}, {
getRings: {
method: 'GET',
isArray: true
},
patchRing: {
method: 'PATCH',
params: {
slug: '#slug'
}
}
}
Get Rings is doing ok, but How can I "patchRing"? I mean I want to PATCH for endpoint: /rings/:slug Is this possible? or Do I need another $resource for that (like next one)?
return $resource('/rings/:slug', { slug: '#slug'}, { [...]
EDIT: I don't want the "PATCH" like this /rings?slug=lorem just /rings/lorem
EDIT 2: My point is only the endpoint construction... because $resource is requesting to /rings?slug=lorem instead of build request like /rings/lorem
Try this in your config
$resourceProvider.defaults.stripTrailingSlashes = true;
This will not end as /
Try putting the param in the $resource definition instead of the PATCH method:
var Ring = $resource('/rings/:slug', {slug: '#slug'}, {
getRings: {
method: 'GET',
isArray: true
},
patchRing: {
method: 'PATCH',
}
});
ring = Ring.patch({slug: 'lorem'}, function() { ... });
If the slug parameter is not passed, then it is not added to the HTTP path.

AngularJS Response does not match configured parameter

I've got a problem with service configuration. I want to display one user by this function:
$scope.findOne = function() {
$scope.user = Users.get({
userId: $stateParams.userId
});
};
But I am in trouble with User service :( I don't know, how should I change my the code to avoid angular error:
Error in resource configuration for action object. Expected response
to contain an array but got an {2}
Here is a code of my actual working service (without function findOne working of course:))
'use strict';
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
},
remove: {
method: 'DELETE',
url: 'users/:id',
params: {id: '#_id'}
}
});
}
]);
At a guess, I'd say your users API endpoint is expecting /users/:userId for GET requests. Your code at the moment will request /users?userId=nnn. You need to add an action for get with the ID in the URL, eg
return $resource('users', {id: '#userId'}, {
get: {
method: 'GET',
url: 'users/:id',
isArray: false
},
// etc
You can also make users/:id the default URL as long as it doesn't interfere with your other action configurations.

Use of '#' in angular resource - am I doing it wrong?

Here's my resource:
.factory('Posting', ['$resource', function ($resource) {
return $resource('api/Postings/:action/:arg', {}, {
findByParent: { method: 'GET', params: { action: 'parent', arg: '#guid' }, isArray: true },
findByReference: { method: 'GET', params: { action: 'reference', arg: '#reference' }, isArray: true }
});
}]);
In my controller I'm using my resource as this:
Posting.findByParent({ guid: parent_guid },
function (success) {
...
},
function (error) {
...
});
This returns the URL /parent?guid=0ff646e9-4397-4654-b8d2-118c6258023a
However, using my resource like this:
Posting.findByParent({ arg: parent_guid },
function (success) {
...
},
function (error) {
...
});
Gives me the correct URL: /parent/0ff646e9-4397-4654-b8d2-118c6258023a
I thought the point with using an '#' was to give parameters better names?
I'm also wondering if I still should use $resource even tho my API isn't really RESTful.
Is it better to give my custom (unRESTful) functions their own URL? Something like:
findByParent: { method: 'GET', url: 'api/Postings/parent/:guid', params { guid: '#guid' }, isArray:true }
By default, if you define a parameter on the path (like you did with arg), and you pass in an object that has a matching key, like in the second example, that key will be used to resolve the path.
If however, there are no matching parameter, the keys of the object passed in will resolve to query parameters, like in the first example.
To set custom default resolves, you need to specify them in the second argument to resource, like this:
.factory('Posting', ['$resource', function ($resource) {
return $resource('api/Postings/:action/:arg',
{
action: '#action',
arg: '#guid'
},
{
findByParent: { method: 'GET', params: { action: 'parent' }, isArray: true },
findByReference: { method: 'GET', params: { action: 'reference' }, isArray: true }
});
}]);
This should make action resolve to what is specified in findByParent and findByReference, and arg to whatever value is passed in for key guid.
You could experiment with setting an # in the respective methods 'guid' property, but for your usecase, it does not seem to be necessary.
to answer your second question: you can specify several parameter controllers on a single path element (level). The only condition is that you don't use / specify resolutions for more than one of them in a single method. That is, you could do api/Postings/:action:anotherController/:arg, as long as you would specify resolutions for :action and :anotherController in separate methods.
Please find this awesome post by Ben Nadel http://www.bennadel.com/blog/2433-using-restful-controllers-in-an-angularjs-resource.htm with an example use

Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an array but got an object?

How fix Error:
[$resource:badcfg] Error in resource configuration. Expected response
to contain an array but got an object?
// Service
angular.module('admin.services', ['ngResource'])
// GET TASK LIST ACTIVITY
.factory('getTaskService', function($resource) {
return $resource('../rest/api.php?method=getTask&q=*',{ 'get': {method:'GET'}});
})
// Controller
$scope.getTask = getTaskService.query(function (response) {
angular.forEach(response, function (item) {
if (item.numFound > 0) {
for(var i = 0; i < item.numFound; i++) {
$scope.getTasks[i] = item.docs[i];
}
}
});
});
Also, if your service is sending an object instead of an array add isArray:false to its declaration.
'query': {method: 'GET', isArray: false }
$resource("../rest/api"}).get();
returns an object.
$resource("../rest/api").query();
returns an array.
You must use :
return $resource('../rest/api.php?method=getTask&q=*').query();
First of all you should configure $resource in different manner: without query params in the URL. Default query parameters may be passed as properties of the second parameter in resource(url, paramDefaults, actions). It is also to be mentioned that you configure get method of resource and using query instead.
Service
angular.module('admin.services', ['ngResource'])
// GET TASK LIST ACTIVITY
.factory('getTaskService', function($resource) {
return $resource(
'../rest/api.php',
{ method: 'getTask', q: '*' }, // Query parameters
{'query': { method: 'GET' }}
);
})
Documentation
http://docs.angularjs.org/api/ngResource.$resource
In order to handle arrays with the $resource service, it's suggested that you use the query method. As you can see below, the query method is built to handle arrays.
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
User $resource("apiUrl").query();
Make sure you are sending the proper parameters too. This happened to me after switching to UI-Router.
To fix it, I changed $routeParams to use $stateParams in my controller. The main issue was that $stateParams was no longer sending a proper parameter to the resource.
For anyone coming here in 2021, another way this request may look is as follows (at least it was in our app)
angular.module('load').factory('StateService', ['$resource', 'store', function($resource, store) {
return $resource('/some/url', {}, {
fetchAllStateCodes: {
method: 'GET',
isArray: true, // Response is an array of objects
headers: {
"Authorization": "Bearer " + store.get("jwt"),
"Content-type": "application/json"
}
}
});
}]);
From all of the good answers, it still wasn't obvious to me as to where to put the isArray flag...

Resources