Multiple parameters in AngularJS $resource GET - javascript

'use strict';
angular.module('rmaServices', ['ngResource'])
.factory('rmaService', ['$resource',
function ($resource) {
return $resource(
'/RMAServerMav/webresources/com.pako.entity.rma/:id',
{},
{
delete: { method: 'DELETE', params: {id: '#rmaId'}},
update: { method: 'PUT', params: {id: '#rmaId'}},
//RMAServerMav/webresources/com.pako.entity.rma/0/3
findRange:{method: 'GET', params:{id:'#rmaId'/'#rmaId'}}
});
}]);
RMAServerMav/webresources/com.pako.entity.rma/0/3
This is correct way to use findRange REST service. This one returns the rmaID from 1 to 4, but how can I use this from controller and what is the correct syntax in service?
In controller I would like to use it something like that:
$scope.rmas = rmaService.findRange({id:'0'/'3'});
but this is not working.

You can override url, Read $resource docs
url – {string} – action specific url override. The url templating is supported just like for the resource-level urls.
In resource declaration
findRange:{
url: '/RMAServerMav/webresources/com.pako.entity.rma/:id/:to',
method: 'GET',
params:{
id:'#id',
to: '#to'
}
}
In Controller
$scope.rmas = rmaService.findRange({id:0, to: 3});

I would prefer shorter way of defining parameters. Here is a complete example.
We have here 2 params :latitude and :longitude they defined only in the URL. Method get is already defined by ngResource
angular.module('myApp', ['ngResource'])
.controller('myCtrl', function (ReverseGeocoderResource) {
ReverseGeocoderResource.get({longitude: 30.34, latitude: 59.97}).$promise.then(function (data) {
console.log(data.address.road + ' ' + data.address.house_number);
})
})
.factory('ReverseGeocoderResource', function ($resource) {
return $resource('https://nominatim.openstreetmap.org/reverse?format=json&lat=:latitude&lon=:longitude&zoom=18&addressdetails=1&accept-language=ru');
});

Try changing your service using it in the controller like this:
'use strict';
angular.module('rmaServices', ['ngResource'])
.factory('rmaService', ['$resource',
function ($resource) {
var service ={}
service.rma = function(){ // name it whatever you want
return $resource(
'/RMAServerMav/webresources/com.pako.entity.rma/:id',
{},
{
delete: { method: 'DELETE', params: {id: '#rmaId'}},
update: { method: 'PUT', params: {id: '#rmaId'}},
//RMAServerMav/webresources/com.pako.entity.rma/0/3
findRange:{method: 'GET', params:{id:'#rmaId'/'#rmaId'}}
});
};
return service;
}]);
//in controller
rmaService.rma()
.then(function(resource){
$scope.rmas = resource.$findRange({id:'0'/'3'});
});
I have no idea if this will work BTW, because I have no use ngResource but that is how I code my factory services.

Related

How to pass parameter inside Angular.js query service the proper way?

I'm trying to pass the folder name inside my query function.
In my controller, I have:
$scope.people = getResult.query({api: 'person'});
And in my services, I have, so far:
.factory('getResult', function($resource) {
var getResult = $resource('api/:path/:method/:id', {}, {
query: {method:'GET', params: {path:'#api', method:'get'}, isArray:true },
save: {method:'POST', params: {method:'save'} },
get: {method:'GET', params: {method:'edit'} },
remove: {method:'DELETE', params: {method:'remove'} }
});
return getResult;
});
The URL I'm getting is http://localhost/project/api/get?api=person but what I need is http://localhost/coral/api/person/get
I'm a newbie to Angular. What is the right way to do this, and why this is happening?
var getResult = $resource('api/:path/:method/:id',{path:'#api'}, {
query: {method:'GET', params: {method:'get'}, isArray:true },

Angular JS: Get subproperty from service response

I am just starting out with Angular and trying to adapt a tutorial I have been following.
I have a resource defined as:
.factory('Session', function ($resource) {
return $resource('http://localhost/api/sessions');
});
I am trying to use the response with a controller like this:
.controller('SessionsCtrl', function($scope, Session) {
$scope.sessions = Session.query();
})
The problem I am coming up against is the format of the JSON response has the sessions in a subproperty as such:
{
sessions: [
{
id: 1,
title: "Welcome"
{
id: 2,
title: "Session 1"
}
]
}
How do I get the resource to look as the sessions property?
If your service is sending an object instead of an array, you should add isArray: false to its declaration:
yourApp.factory('Session', function ($resource) {
return $resource(
'http://localhost/api/sessions',
{},
{'query': {method: 'GET', isArray: false }}
);
});
In your controller you can use a callback:
yourApp.controller('SessionsCtrl', function($scope, Session) {
$scope.sessions = Session.query(function(result) {
return result.sessions;
});
});

Angular wp-api cannot get headers for X_Total_Pages

I'm using Angular wp-api module and each time my $resource request responds I can see the ResponseHeaders in Chrome with X_Total_Pages and other header information. But I cannot add them to the scope.
Here is my controller...
.controller('newslettersController', ['$scope','$stateParams','$sce','WPFactory', function ($scope,$stateParams,$sce,WPFactory) {
$scope.newsletters = WPFactory.query({
param1: 'posts',
page: $scope.pageNum,
'filter[cat]': 8,
'filter[posts_per_page]' : 10,
'filter[orderby]': 'ID'
}, function(data, reponseHeaders) {
$scope.header = reponseHeaders('X_Total_Pages');
});
});
}]);
And my factory...
.factory("WPFactory", function($resource) {
var dataResponse = $resource('http://www.example.com/wp-json/:param1/:param2/:param3/:param4/:param6/:param7', {}, {
get: {
method: 'GET'
}
});
return dataResponse;
})
is this jeffsebrings angular module? If it is I think you need to inject your service with wpAPIResource:
.factory("WPFactory", function($resource, wpAPIResource)
and use it to query the json rest api (wp-api).
Also, not sure if your controller is passing the query object quite right:
I would change up your factory something like this:
.factory("WPFactory", function(wpAPIResource) {
var posts_query = function(args) {
return wpAPIResource.query(args);
};
return posts_query;
})

AngularJS, creating a resource hash

Trying to take a url and in an AngularJS controller redirect that request to the best place to get the json data. The VideoSearchCtrl is bound to the search form. The url generated is correct for the template so I'm using the controller to redirect it to the place for the json data.
GuideControllers.controller('VideoSearchCtrl', ['$scope', 'VideoSearch',
function($scope, VideoSearch) {
var pattern = new RegExp(".*/search\\?=(.*)");
var params = pattern.exec( document.URL )[1];//redirect to videos to execute the search for the data
$scope.videos = VideoSearch.query({ resource: "videos", action: "search", q: params });
}
]);
This sends /videos/search?q=xyz in to the query. The factory creates the resource:
var VideoSearchServices = angular.module('VideoSearchServices', ['ngResource']);
VideoSearchServices.factory('VideoSearch', ['$resource',
function($resource){
return $resource("/:resource/:action:params", {resource: "#resource", action: "#action", params: "#params"}, {
query: {
isArray: true,
method: "GET",
headers: {
"Accept": "application/json",
"X-Requested-With": "XMLHttpRequest"
}
}
});
}
]);
But the server gets the url as /videos/search%fq=xyz, not /videos/search?q=xyz and therefore the "show" method is being invoked instead of a custom "search" action. Obviously there is some escaping somewhere? Or maybe the "?" is also a special pattern the resource factory looks for? Probably obvious to someone used to AngularJS or javascript for that matter.
I have a template for search and the json is retrieved from a different location. Both work but I can't ask for the json with the above code.
First, do:
return $resource("/:resource/:action", {resource: "#resource", action: "#action"}, {
Then:
$scope.videos = VideoSearch.query({ resource: "videos", action: "search", q: params });
The point is params are not a part of the url you have to declare to the resource, you just declare resource and action then you add params which is natural for all routes
Actually there is a better way to do this with $location from Angular and jQuery's extend that should work with any future params that are added. Will only have to add the new params to the query factory.
GuideControllers.controller('VideoSearchCtrl', ['$scope', '$location', 'VideoSearch',
function($scope, $location, VideoSearch) {
var route = jQuery.extend(
{ resource: "videos", action: 'search' },
$location.search()
);
$scope.videos = VideoSearch.query(route);
}
]);

Default $resource POST data

That might be strange but I need to specify some default POST data for my $resource using the factory method of the module.
Does anyone have an idea of how to do that in AngularJS ?
EDIT :
Well, i want to do something like this :
/**
* Module declaration.
* #type {Object}
*/
var services = angular.module("services", ["ngResource"]);
/**
* Product handler service
*/
services.factory("Product", function($resource) {
return $resource("http://someUrl", {}, {
get : {method: "GET", params: {productId: "-1"}},
update: {method : "POST", params:{}, data: {someDataKey: someDataValue}}
});
});
Where data is the default data for my future POST requests.
This is not really the angular way to do such a thing as you lose data consistency if you do it and it doesn't reflect in your model.
Why?
The resource factory creates the object and uses object instance data as POST. I have looked at the documentation and angular-resource.js and there doesn't seem to be a way to specify any default custom properties for the object being created by resource without modifying angular-resource.js.
What you can do is:
services.factory("Product", function($resource) {
return $resource("http://someUrl", {}, {
get : {method: "GET", params: {productId: "-1"}},
update: {method : "POST"}
});
});
and in your controller:
$scope.product = {}; // your product data initialization stuff
$scope.product.someDataKey = 'someDataValue'; // add your default data
var product = new Product($scope.product);
product.$update();
I think it will depend on how you call the update function. If you read the angular main page's tutorial, under "Wire up a Backend", the mongolab.js provides a 'Project' factory. Copied verbatim:
angular.module('mongolab', ['ngResource']).
factory('Project', function($resource) {
var Project = $resource('https://api.mongolab.com/api/1/databases' +
'/angularjs/collections/projects/:id',
{ apiKey: '4f847ad3e4b08a2eed5f3b54' }, {
update: { method: 'PUT' }
}
);
Project.prototype.update = function(cb) {
return Project.update({id: this._id.$oid},
angular.extend({}, this, {_id:undefined}), cb);
};
Project.prototype.destroy = function(cb) {
return Project.remove({id: this._id.$oid}, cb);
};
return Project;
});
The usage is that you first get an instance of the Project:
project = Project.get({id:1});
Then do an update after some changes:
project.update(someFunction);
In your case, you can change the update to always add the data you need:
Product.prototype.update = function(cb) {
return Product.update({},
angular.extend({}, this, {someDataKey: someDataValue}), cb);
};
Otherwise, you can most likely put the key/value pair in the params:
update: {method : "POST", params:{someDataKey: someDataValue}}
It will be POSTed with the key/value pair in the URL, but most app servers nowadays will throw the pair into the params object anyway.
I think most have missed a tiny gem in the documentation here.
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
This suggests you can do the following.
var User = $resource('/user');
postData = { name : 'Sunil', 'surname' : 'Shantha' };
var user = User.save({notify:'true'}, postData, function() {
// success!
});
The second parameter when doing a save action (post) is post data.
Wrapper function will work.
function myPost(data) {
return $http.post('http://google.com', angular.extend({default: 'value'}, data))
}
myPost().success(function(response) { ... });
Might this solve your problem?
services.factory("Product", function($resource) {
return $resource("http://someUrl", {}, {
get : {method: "GET", params: {productId: "-1"}},
update: {method : "POST", params:{}, data: {someDataKey: someDataValue}}
});
});
services.factory("DefaultProduct", function(Product) {
return function(){
return new Product({
data:"default";
});
};
});
services.controller("ProductCTRL",function($scope,DefaultProduct){
$scope.product = new DefaultProduct();
});
You can just merge your params with the default. Everything not available in params will be provided by the default object. Everything available will be overwritten by myParams
services.factory("Product", function($resource) {
return $resource("http://someUrl", {}, {
get : {method: "GET", params: {productId: "-1"}},
update: {method : "POST", params:angular.extend(myDefault, myParams);}
});
});
where myParams would be your list of variables and myDefault your default values as a json object.
You can set default fields on your request by using transformRequest option for your $resource's actions that use the POST method.
For example something like this
function prependTransform(defaults, transform) {
// We can't guarantee that the default transformation is an array
defaults = angular.isArray(defaults) ? defaults : [defaults];
// Append the new transformation to the defaults
return [transform].concat(defaults);
}
ctrl.factory('MyResource', ['$resource', '$http',
function($resource, $http) {
return $resource('/path/to/myresource/:id', {id : '#id'},
{
create : {
method : 'POST',
transformRequest : prependTransform($http.defaults.transformRequest,
function(data, headers) {
return addDefaultField(data);
}
),
},
});
}
]);

Categories