This is possibly just the way I am accessing the resource object but I have the service below:
angular.module('appointeddPortalApp')
.factory('Salon', function ($resource) {
// Service logic
// ...
// Public API here
return $resource('http://api.appointeddcore.dev/organisation/:id', {id: '#id'}, {
update: { method: 'PUT' },
query: { method: 'GET', isArray: false}
});
});
I'm using the query method like this:
var data = Salon.query($scope.options);
console.log(data);
From the console.log() :
Resource {$get: function, $save: function, $query: function, $remove:
function, $delete: function…}
offices: Array[20]
total: 33
__proto__: Resource
My problem is trying to access total or offices I get undefined
console.log(data.total); // undefined
Because Salon.query() returns immediately with an empty object and updates the variable data if the data is present, try this:
var data = Salon.query(function(callbackdata){
//function is called on success
console.log(callbackdata);
console.log(callbackdata.total);
});
Related
I have a problem with angular-ui typeahead component. It does not show values populated by angular resources, however using $http works well. I suppose I missing some trick here with asycn call and correct population of returned values.
Working code
$scope.searchForContact = function(val) {
return $http.get('/api/contacts/search', {
params: {
q: val
}
}).then(function(response){
return response.data.map(function(item){
return item.name;
});
});
};
Not working code
$scope.searchForContact = function(val) {
return Contact.search({q: val}, function(response){
return response.map(function(item){
return item.name;
});
});
});
...
'use strict';
app.factory("Contact", function($resource, $http) {
var resource = $resource("/api/contacts/:id", { id: "#_id" },
{
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'search': { method: 'GET', isArray: true, url: '/api/contacts/search', params: true },
'show': { method: 'GET', isArray: false },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
}
);
return resource;
});
Pug template code
input.form-control(
type='text'
ng-model='asyncSelected'
uib-typeahead='contact for contact in searchForContact($viewValue)'
typeahead-loading='loadingLocations'
typeahead-no-results='noResults'
)
i.glyphicon.glyphicon-refresh(ng-show='loadingLocations')
div(ng-show='noResults')
i.glyphicon.glyphicon-remove
|
|No Results Found
Angular resources are working fine, including search endpoint - I just output on page result returned by the search endpoint. In both results should be just an array with string values. What am I doing wrong?
The difference between $http.get and your Contact.search is that the first one returns a promise and the latter doesn't. Any $resource method will usually be resolved to the actual response. I'll show that with an example.
Getting data with $http
var httpResult = $http.get('http://some.url/someResource').then(function(response) {
return response.map(function(item) { return item.name });
});
The httpResult object contains a promise, so we need to use then method to get the actual data. Moreover, the promise will be resolved to the mapped array, which is the expected result.
Getting data with $resource
var someResource = $resource('http://some.url/someResource');
var resourceResult = someResource.query(function(response) {
return response.map(function(item) { return item.name });
});
The resourceResult isn't a promise here. It's a $resource object which will contain the actual data after the response comes from the server (in short, resourceResult will be the array of contacts - the original, not mapped, even though there is a map function). However, the $resource object contains a $promise property which is a promise similar to one returned by $http.get. It might be useful in this case.
Solution
I read in documentation that in order to make uib-typehead work properly, the $scope.searchForContact needs to return a promise. Instead of passing the callback function to search, I would simply chain it with the $promise from $resource object to make it work.
$scope.searchForContact = function(val) {
return Contact.search({q: val}).$promise.then(function(response){
return response.map(function(item){
return item.name;
});
});
});
Let me know if it works for you.
I have added a custom action to a $resource:
var myResource = $resource('some/url/:someParam',
{
someParam: '#someParam'
},
{
update: {
method: 'PUT'
}
});
I am attempting to have a function run on completion. According to Angular's documentation, I'd do it in the following way:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
Yet the following never invokes the success function even though the request is successful:
myResource.update({ someParam: 'a value' }, { myPostData: 'goes here' }, function(a,b) {
// this function never gets invoked
});
The documentation also says this:
The Resource instances and collections have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
But this doesn't work either:
myResource.update({ someParam: 'a value' }, { myPostData: 'goes here' }).$promise.then(function() {
// do stuff
});
Am I missing something here? Any help would be greatly appreciated.
I'm trying to pass a params object to the $http.get() service. My params look like this:
var params = {
one: value,
two: value
}
And I'm trying to pass them into my function like so:
$http.get('/someUrl', params)
.success(function(data) {
// stuff
})
.error(function(data) {
// error stuff
});
Is this the correct way to go about doing this?
The second argument of $http is a config object (see documentation). Amongst other properties, the config object accepts a params property:
params – {Object.<string|Object>} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters.
Therefore you have to pass the parameters as such
var config = {
params: {
one: value,
two: value
}
}
$http.get('/someUrl', config).then(...)
Suppose the values for the parameters are respectively '1' and '2', $http will send a GET request to the following url:
/someUrl?one=1&two=2
As a side note, try to avoid using success and error functions on $http. They have been deprecated as of angular 1.4.4. Use the methods then with a success and an error callback instead, or then with only a success callback and catch.
Service/Factory
For the actual call use a factory or service that you can inject to the controllers you need it in. This is an example factory passing parameters
.factory('Chats', function ($http, $rootScope, $stateParams) {
return {
all: function () {
return $http.get('http://ip_address_or_url:3000/chats', { params: { user_id: $rootScope.session } })
}
};
});
Controller
In your controller you use the service like this
.controller('ChatsCtrl', function ($scope, Chats) {
Chats.all().success(function (response) {
$scope.chats = response;
})
})
I have faced similar issue in recent time and I had to add few additional details to request (I used accepted answer with some headers):
$http.get(url, {
params: {
paramOne: valueOne,
paramTwo: valueTwo,
...
},
headers: {
'key': 'value'
},
// responseType was required in my case as I was basically
// retrieving PDf document using this REST endpoint
// This is not required in your case,
// keeping it for somebody else's reference
responseType: 'arraybuffer'
}).success(
function(data, status, headers, config) {
// do some stuff here with data
}).error(function(data) {
// do some stuff here with data
});
The $http documentation suggest that the second argument to the $http.get method is an object which you can pass with it "param" object.
Try something like this:
$http.get('/someUrl', {params: params})
.success(function(data) {
// stuff
})
.error(function(data) {
// error stuff
});
Code
MyClass = Backbone.Model.extend({
url: '/apiurl/'+sessionValue+'',
defaults: {
data1: '',
data2: 1
}
});
var myobj = new MyClass ();
var myobjvalue = {
data1: "myvalue"
};
myobj.save(myobjvalue , {
success: function (myobj , response) {
alert("success");
},
error : function (myobj , response) {
var data = JSON.stringify(response);
console.log(data);
}
})
in the above code, save function successfully calls the REST api. (200 OK). However even after that it enters in error block.
value printed in console
{"readyState":4,"responseText":"Success","status":200,"statusText":"OK"}
What should I be doing?
===================================
What worked
Instead of string, I had to return actual object as part of REST API. apprently, backbone expects class object along with HTTP status. so responseText contained full myobj.
What worked
Instead of string, I had to return actual object as part of REST API. apprently, backbone expects class object along with HTTP status. so responseText contained full myobj.
I am trying to use $resource to get data from a static json file and here is the code snippet :
angular.module('app.services', ['ngResource']).
factory('profilelist',function($resource){
return $resource('services/profiles/profilelist.json',{},{
query:{method:'GET'}
});
});
In the controller,
function ProfileCtrl($scope,profilelist) {
$scope.items = [];
$scope.profileslist = profilelist.query();
for (var i=0;i<=$scope.profileslist.length;i++){
if($scope.profileslist[i] && $scope.profileslist[i].profileid){
var temp_profile = $scope.profileslist[i].profileid;
}
$scope.items.push(temp_profile);
}
But now, I am facing an error :
TypeError: Object #<Resource> has no method 'push'
Could you please help me where I am going wrong ?
You don't need to specify actions parameter for default $resource methods (these are 'get', 'save', 'query', 'remove', 'delete'). In this case you can use .query() method as is (this requires only service definition to be chaged):
angular.module('app.services', ['ngResource']).
factory('profilelist',function($resource){
return $resource('services/profiles/profilelist.json');
});
P.S. And one more hint is that your example unwrapped json into hash rather then array (that's why you received no push method error), if you need it to be an array set isArray: true to action config:
'query': {method:'GET', isArray:true}
And as #finishingmove spotted you really can't assign $resource result to obtain immediately, provide callback:
$scope.profileslist = profilelist.query(function (response) {
angular.forEach(response, function (item) {
if (item.profileid) {
$scope.items.push(item.profileid);
}
});
});