Angularjs: How to use $resource to serve an array of objects - angularjs

I had a $resource that servers two files, names.js and birthday.js:
// names.js
{
name: John,
name: Mary,
}
// birthday.js
{
John: 28,
Mary: 28
}
It works great in my controller. But I couldn't run ng-repeat on it. So I converted the data to a format that was used in the ng-repeat docs:
// friends.js
friends = [{name:'John', age:25}, {name:'Mary', age:28}];
But now my provider for friends.js returns an array of characters (not very useful) or an object of characters. How can I make it so that my provider returns a useful format of the data?
The query in the service is:
friends: $resource('data/friends.js', {}, {
query: {method: 'GET', params: {}, isArray: true[or false]}
})
In short, how do you use a $resource to provide friends.js?

How do you query your $resource?
The get method is expecting an object while the query method is expecting an array.
This is the default methods available on a $resource :
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
More info available here :
AngularJS resource documentation

Related

Angular - correct approach to handle the data fetch from server?

Assume that, I am using the angular-resource - module with my ng-app. I don't able to understand the data handling easy and scale able way.. any one give me / show me a correct way to answering all this questions?
a) Generally how to fetch data from url in the angular.?
b) in case each of the controller may require different url and data if so how the fetch process added on each of controller.?
c) or need we make a service to provide the data according to the controllers parameters - if so how to pass parametes to service?
d) All above have GET, PUT and DELETE, 'POST` then how to handle all them - is all this need separate services?
Thanks in advance.
Use angular-resource as you said within a service/factory. It already provides a lot of your requirements:
myApp.factory("dataService", [
"$resource",
function ($resource) {
return $resource("http://someBaseUrl/:action/:id", {
id: "#id" // default parameters
},
{
// custom methods
update: { method: "PUT" },
doOtherStuff: { method: "GET", action: "DoOtherStuff" }
});
}
]);
The $resource default provides for the following REST compliant functions:
{
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
Any other functions you have to include yourself, like the update and the doOtherStuff in the example above.
The :action part is an easy way to provide any custom action, that is not REST compliant.
Usage in controllers:
myApp.controller("myCtrl", [
"dataService",
function (dataService) {
// first parameter can be used for any extra query parameters
// second parameter always is a callback
var myData = dataService.query({}, function() {
// success
});
var mySingleInstance = dataService.get({ id: 12 });
this.doUpdate = function (entity) {
dataService.update(entity);
// Or, if the 'entity' is a resource entity:
// entity.$update();
}
this.customMethod = function () {
dataService.doOtherStuff();
}
}
]);
See https://docs.angularjs.org/api/ngResource/service/$resource for the full documentation

Alter $resource default methods

How can I alter and add to the default $resource return object methods?
The return object defaults in question are (from the docs):
A resource "class" object with methods for the default set of resource actions optionally extended with custom actions. The default set contains these actions:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
As I understand, this does not follow the restful principles so good in regard to when to use POST and PUT. Perhaps it would be better to have the following methods:
{ 'get': {method:'GET'},
'save': {method:'PUT'},
'create': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
Is there a way to change the default object that $resource creates, so I do not need to alter each resource I am creating with $resource?
I found a talk at ng-conf 2014 by Googles DoubleClick team that was a real good answer to this question and beyond. Basically they create a apiProvider that uses and extends $resource.
They also have a github gist that would be too long to include here.

Understanding angularJS $resource isArray property

i'm learning angular's $resource service and in the angular tutorial a custom action is added (query) that has its method set to 'get' and isArray is set to true
return $resource('phones/:phoneId.json', {}, {
query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
});
However, if you look at the docs for $resource the 'query' action already has its method set to 'get' and isArray is already set to true by default. So i thought that i can just leave those properties out.
This works for the method property, but it turns out that if i leave out the isArray property i get this error:
Error: [$resource:badcfg] Error in resource configuration for action
query. Expected response to contain an object but got an array
Why is that?
I think you have misunderstood the documentation.
By default without adding any custom actions, the following are supported:
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
So by default the query action expects an array to be returned which makes sense since a query generally would return an array of items.
So if you use:
phonecatServices.factory('Phone', ['$resource', function($resource){
return $resource('phones/phones.json');
}]);
You can then perform a query like so:
var queryParams = { name: 'test' };
Phone.query(queryParams, {}, function (response) {
$scope.phones = response;
});
Now if you wanted to add a custom action then the default for isArray is false so:
return $resource('phones/:phoneId.json', {}, {
someCustomAction: {method:'GET', params:{phoneId:'phones'} }
});
would need to return an object. If an array was returned then isArray would need to be set to true like so:
return $resource('phones/:phoneId.json', {}, {
someCustomAction: {method:'GET', params:{phoneId:'phones'}, isArray: true }
});

How to retrieve objects from rest url with multiple parameters using angular

How can i create a factory that can retrieve data from
/rest/company/:companyid/employee/:id
when i use this url in the factory I get an error: Unknown provider companyidProvider
Thank you,
Kyle
Service:
app.factory('EmployeeByCompany', function ($resource,companyid) {
return $resource('app/rest/company/:companyid/employee/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': { method: 'GET'}
});
});
I'm guessing the error is from having the companyid as a parameter with $resource. What is the right way for a service to call this url?
If you are learning or geting started, try Restangular https://github.com/mgonto/restangular

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