How do I call $resource service from controller in angularJs - angularjs

This is get service function where I am calling the API
.factory('Report', function($resource, API_URL) {
return $resource(API_URL +
'security/:userId/1498780800000/listOfDeliveries', {
userId : '#userId',
expected : '#expected',
arg1 : '#arg1'
}, {
update: {
method: 'PUT'
}
});
})
In the app.js I have this below controller
.controller('ReportsController', function($scope, $rootScope,
ProfileData, $state, $timeout, Report) {
})

First of all, you need to check how angular factory & service work.
Your factory return a $resource, so read the doc about $resource
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'}
};
So, you can use theses methods: Report.get(), Report.save(), Report.query(), Report.remove(), Report.delete()
In addition there are custom method you defined: Report.update()
And you can pass userId as params so:
Report.get({userId: 1234}); will call a GET request to: API_URL+'security/1234/1498780800000/listOfDeliveries
(expected and args1 are not in url so I dont think you need them)
What's returning Report.get() ?
Class actions return empty instance (with additional properties below). Instance actions return promise of the action
So Report.get(...) is returning a promise, you will get data by:
Report.get(...).then(function(data) {
$scope.requestData = data;
});

Related

Angularjs $resource query method working but get method not working

Here is my factory method:
.factory('lettersFactory', ['$resource', function ($resource) {
var url = "";
if(ionic.Platform.isAndroid()){
url = "/android_asset/www/";
}
return $resource(url + 'data/letters.json');
}])
And here is the controller:
.controller('LettersCtrl', ['$scope','lettersFactory', '$stateParams', '$state', '$ionicPopover', function($scope, lettersFactory, $stateParams, $state, $ionicPopover) {
$scope.letters = lettersFactory.query();
$scope.letter = lettersFactory.get({number:parseInt($stateParams.letterId, 10)});
}])
And here is the Error message:
Error in resource configuration for action object. Expected response to contain an array but got an GET (Request: data/letters.json {4})
And my letter.json is an array like this:
[
{"number":1,
"title": "title",
"content": "content"},
{"number":1,
"title": "title",
"content": "content"}
]
Thanks
If the response should not be an array then you need set the isArray as false in query property.
'query': {method: 'GET', isArray: false }
Refer to the document.https://docs.angularjs.org/api/ngResource/service/$resource
Or you can pass the json as array from the controller.
The default method set for $resource contains these actions1:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
In your case the get method is failing because the data from the XHR is an array and the method expects an object.
The query method succeeds because the data from the XHR is an array and the method expects an array.
Use the get method for object data; use the query method for array data.
Update
how do you think I can use the query method in this situation to get a particular object from the array data?
One approach is to use the $promise property of the returned resource object:
$scope.array = lettersFactory.query();
$scope.array.$promise.then(function(resourceArray) {
$scope.item = resourceArray[0];
});
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.
The Resource instances and collections have additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
On success, the promise is resolved with the same resource instance or collection object, updated with data from server.
On failure, the promise is rejected with the http response object, without the resource property.
For more information, see AngularJS $resource API Reference

Angular $resource action return $resource of different class

So I have a services.js that looks something like this.
.factory('User', function($resource) {
return $resource('/api/users/:id/', {'id': '#id'}, {
groups: {
method: 'GET',
url: '/api/users/:id/groups',
isArray: true
}
});
})
.factory('Group', function($resource) {
return $resource('/api/groups/:id/', {'id': '#id'}, {
update: {
method: 'PUT'
}
});
})
Users in the db have an implicit relationship to Groups via a JSONField of ids (implicit in that it is not an explicit one2m or m2m). I have a custom endpoint on my api server '/api/users/:id/groups' that returns a serialized array of Group instances. My issue is that the User::groups action on the angular side is returning an array of the Group instances BUT with the actions of the USER resource instead of the GROUP resource. Is there any way for the custom action of a $resource to return an instance of a $resource from a different class?
Thanks!

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

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 }
});

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