ngResource.myfunc().$promise.then returns empty array - javascript

I'm using angularjs-1.5.0 to write my application.
I created a service that uses a $resource to fetch data from the api server. the service is called MyApi.
(function () {
angular.module('myalcoholist').factory('MyApi', ['$resource', '$auth', function ($resource, $auth) {
return $resource('https://myalcoholist.com:8888/drink/:cmd',
null, {
pouringSpeedTypes: {
method: 'GET',
params: {api_token: $auth.getToken(), cmd: 'get_pouring_speed_types'},
isArray: true
},
pouringLocationTypes: {
method: 'GET',
params: {api_token: $auth.getToken(), cmd: 'get_pouring_location_types'},
isArray: true
}
});
});
}]);
})();
and in my controller i use this service using the following code:
MyApi.pouringLocationTypes().$promise.then(function(data) {
console.info(data);
});
MyApi.pouringSpeedTypes().$promise.then(function (data) {
console.info(data);
});
the problem is that the data is.. a promise i guess.
this is what data contains:
$promise: d
$resolved: true
length: 0
__proto__: Array[0]
what do I do with that? how do I get the actual data from the get request ?

thank you for your comments, you allowed me to pinpoint the issue.
first of all I didn't update my server's code that's why when you tried these addresses you got Method not Allowed.
the problem that i've been having is that these requests really returned empty arrays.
so first of all my API returns a json Object not an array so i changed isArray to false.
so after that and actually fixing my API Server, this is what I received:
$promise: d
$resolved: true
data: Array[4]
success: true
my API server returns a json with data and success. so things are working now! thanks a lot.

Related

how to add specific interceptor to resource object get() or update() in AngularJS

I am currently using angular-hateoas (https://github.com/jmarquis/angular-hateoas). I would like to add specific interceptors to the query() and get() functions of the resource created in HateoasInterface. I have been looking for ways to do it, but not been successful.
I thought it could be done by adding it like this:
var someResource = someService.resource('someresource');
someResource.query.interceptors = {
response: function (data) {
// do something data
return data
},
responseError: function (error) {
// do something with error
return $q.reject(error);
}
};
but that gives me:
TypeError: Attempted to assign to readonly property.
I might need to use $decorator, but I have no experience with that, and I have seen no example for adding specific interceptors to specific resource objects.
I don't really want to use $httpProvider.interceptors, since I don't want the interceptor to work on all resources.
The only thing I can currently think of, is configuring HateoasInterfaceProvider with specificly named functions that contain the specific interceptors.
angular.module('myModule')
.config(HateoasInterfaceConfig);
HateoasInterfaceConfig.$inject = ['HateoasInterfaceProvider'];
function HateoasInterfaceConfig(HateoasInterfaceProvider) {
HateoasInterfaceProvider.setHttpMethods({
get: {
method: 'GET',
isArray: false
},
getSomeResource: {
method: 'GET',
isArray: false,
interceptors: {
response: someResponseFunc,
responseError: someErrorFunc
}
},
update: {
method: 'POST',
},
query: {
method: 'GET',
isArray: true
}
querySomeResource: {
method: 'GET',
isArray: true,
interceptors: {
response: function(data) {
// do something with data
return data;
},
responseError: function (error) {
//do something with error
return $q.reject(error);
}
}
});
HateoasInterfaceProvider.setLinksKey('_links');
}
but I prefer not to do it like that.
Figured it out.
When calling a resource, params and actions can be passed.
So like:
someServiceResult.resource('someresource',{},{get: {method: 'GET',...,
interceptor: { response: responseInterceptorFunc, ...}}})
Still not really the preferred solution, but when wrapped in a function in a service, acceptible.
I would like to have a solution that allows changing the interceptor definition for the Resource object created with:
someServiceResult.resource('someresource')
but I currently don't have time for figuring that out.

Custom AJAX property within AngularJs Service

Very simple scenario:
Code:
$.ajax({
type: "GET/POST",
url: 'http://somewhere.net/',
data: data,
beforeSend: '', // custom property
}).done().fail();
Basically I am looking for a legit way to modify beforeSend within Angular factory service. Please refer to what I have:
myApp.factory('GetBalance', ['$resource', function ($resource) {
return $resource('/Service/GetBalance', {}, {
query: { method: 'GET', params: {}, }, isArray: true,
});
}]);
Here I am using AngularJs services api problem is the documentation is not very helpful towards what I am trying to achieve.
If you want custom headers to be attached, you can do like this.
myApp.factory('GetBalance', ['$resource', function ($resource) {
return $resource('/Service/GetBalance', {}, {
query: { method: 'GET', params: {}, headers: { 'beforeSend': '' } }, isArray: true,
});
}]);
You might be interested in requestInterceptors, especially on the addFullRequestInterceptor method which has the following parameters:
It can return an object with any (or all) of following properties:
headers: The headers to send
params: The request parameters to send
element: The element to send
httpConfig: The httpConfig to call with
Solution sugested by #Thalaivar should have worked according to Angular docs but for whatever reason it just wouldn't work in my specific use case.
Here I provide an alternative solution that worked out for me as follows:
myApp.config(['$provide', '$httpProvider', function ($provide, $httpProvider) {
// Setup request headers
$httpProvider.defaults.headers.common['modId'] = 1; // dynamic var
$httpProvider.defaults.headers.common['pageId'] = 2; // dynamic var
$httpProvider.defaults.headers.common['token'] = 'xyz'; // dynamic var
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});
I know that headed values are hard coded in my example but in reality things change from page to page so those values are actually dynamically retrieved.
Again if you are using $http based services then you should not need to do this.

Angularjs $resource response is not returning data

I am trying this with $resource I have a service Post
app.factory('Post', function ($resource, $cookieStore) {
return $resource('http://localhost:port/posts/:id', {"id":"#id", port:':9000'}, {
query: { method:'GET', isArray: true , headers: {'X-AUTH-TOKEN':'authToken='+$cookieStore.get("authToken")}},
save: { method:'POST',headers: {'X-AUTH-TOKEN':'authToken='+$cookieStore.get("authToken")}},
update: {method:'PUT' ,headers: {'X-AUTH-TOKEN':'authToken='+$cookieStore.get("authToken")}},
delete : {method: 'DELETE',headers: {'X-AUTH-TOKEN':'authToken='+$cookieStore.get("authToken")}},
get : { method: 'GET', headers: {'X-AUTH-TOKEN':'authToken='+$cookieStore.get("authToken")}}
});
});
And the in the controller I am trying to get all the posts.
Post.query(function(data){
console.log(data.length);
console.log(data)
});
I was expecting the data to be whats returned from the server but the console.log is showing me this how can I get the access to the actual json data from server?
3 posts.js:18
[Resource, Resource, Resource, $promise: Object, $resolved: true]
0: Resource
1: Resource
2: Resource
$promise: Object
$resolved: true
length: 3
__proto__: Array[0]
According to documentation it seems that first parameter in action is parameter object for query and only then success callback. So try:
Post.query({}, function(data) {
console.log(data.length);
console.log(data);
})
You also can use $promise:
Post.query({}).$promise.then((function(data) {
console.log(data.length);
console.log(data);
})

AngularJS tokenWrapper - wrong callback arguments

AngularJS 1.2.1
ngResource 1.2.1
I got the weirdest problem.
I'm using tokenWrapper by Andy Joslin (AngularJS: How to send auth token with $resource requests?)
I have a resource defined like that:
.factory('someService', ['$resource', 'api_host', 'TokenHandler',
function($resource, api_host, TokenHandler) {
var Resource = $resource(api_host + 'applicant/:command/:xxx', { xxx: '#xxx', command: '#command' }, {
'get': { method: 'GET', isArray: false },
'save': { method: 'POST', isArray: false },
'create': { method: 'put', isArray: false },
'message': { method: 'post', isArray: false }
});
Resource = TokenHandler.wrapActions( Resource,
["query", "get", "save", "remove", "create", "message"] );
return Resource;
}])
its wrapped by tokenHandler and token is sent with every request and thats great.
the problem is with invoking the error callback.
when using the resource like that
var interview = new someService({ command: 'doSomething', xxx: $scope.xxx});
interview.$create({}, function(response) {
console.log(response);
}, function(e) {
alert('error');
});
The Problem
When the resource returns 200 the success function (1st argument) is invoked as it should.
When the resource returns something else, the error callback is not invoked.
I've tried to log the tokenHandler and it seems like the handler is massing up the arguments.
var tokenWrapper = function( resource, action ) {
// copy original action
resource['_' + action] = resource[action];
// create new action wrapping the original and sending token
resource[action] = function( data, success, error){
console.log(success, 'success');
console.log(error, 'error');
return resource['_' + action](
angular.extend({}, data || {}, {token: tokenHandler.get()}),
success,
error
);
};
};
the result of the console.log prints out the data as success and success as error.
how can I fix that?!
angular 1.2.0 changed the way promises are handled. and this look like a promise issue (you are not getting the expected order of suceess``failure```. see this for an example. my guess that insisting on using resource from 1.5 doesn't work we'll with this behavior, so you are not getting the expected data. yes. there are error messages when upgrading. but solving them shouldn't take long.

AngularJS Resource not Resolved

I am new to AngularJS, so please be gentle.
I want to retrieve data from my backend using the $resource property of AngularJS, however it seems that the property is getting loaded before the actual call is completed.
Currently I have the following code:
Controller:
MyApp.controller('IndexCtrl', function IndexCtrl($scope, socket, carsRes) {
console.log(carsRes.cars.get());
$scope.cars = carsRes.cars.get();
});
Factory
.factory('carsRes', function($resource) {
var result = {};
result.cars = $resource('/cars/:id', {}, {
'get': {method: 'GET'},
'save': {method: 'POST'},
'query': {method: 'GET', isArray: true},
'remove': {method: 'DELETE'},
'delete': {method: 'DELETE'}
});
return result;
});
But at the point where I want to store carsRes.cars.get() in $scope.cars the call isn't completed yet, and a console.log tells me that the $resolved is still false.
How can I wait for the call to be resolved? I've read something about $q but it isn't really clear to me.
This is happening because resource.get() is asynchronous. It returns an empty reference immediately, and is then populated with the actual data once the ajax call is complete.
The best way to handle the result is with a callback function:
carsRes.cars.get(function(response){
// We now have a completed ajax call, with the response
$scope.cars = response;
});
See more examples in the $resource documentation.

Categories

Resources