Default $resource POST data

All we need is an easy explanation of the problem, so here it is.

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 ?


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.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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.


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

Method 2

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('' +
      { 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:


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.

Method 3

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 ={notify:'true'}, postData, function() {
  // success!

The second parameter when doing a save action (post) is post data.

Method 4

Wrapper function will work.

function myPost(data) {
  return $'', angular.extend({default: 'value'}, data))

myPost().success(function(response) { ... });

Method 5

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({
  $scope.product = new DefaultProduct();

Method 6

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.

Method 7

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

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply