4

I have a backend that understands query strings in the format jQuery's $.param returns. For instance, having an object like

{ search: "Miller", name: ["Felipe", "Fernanda"] }

Will request the URL with the following query string:

http://theurl/path?search=Miller&name%5B%5D=Felipe&name%5B%5D=Fernanda 

Basically it uses name[]=Felipe&name[]=Fernada, but URL encoded.

The same object, when parsed by AngularJS ends up with this format:

http://theurl/path?search=Miller&name=Felipe,Fernanda

Which my backend doesn't understand.

Reading this other question, I thought that using transformRequest would help, however it doesn't. Here's my testing code:

HTML

<div ng-controller="UserCtrl">
    <pre>{{ data | json}}</pre>
</div>

JavaScript

var myApp = angular.module('myApp',['ngResource']);

var transformFn = function(data, headersGetter) {
    console.debug('transformRequest', data);
    if (!data) return;
    console.debug('data in', data);
    var dataOut = $.param(data);
    console.debug('data out', dataOut);
    return dataOut;
};

myApp.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.transformRequest.push(transformFn);
}]);

myApp.factory('User', ['$resource', function($resource) {
    return $resource('/echo/:type/', {type:'json'}, {
        query: { method: 'GET' }
    });
}]);

myApp.controller('UserCtrl', ['$scope', 'User', function($scope, User) {
    User.query({ seach: 'Miller', name: ['Felipe', 'Fernanda']}, 
       function(data) {
           console.debug('data', data);
           $scope.data = data;
       });
}]);

​However, when you try to run this code, you will notice that the data attribute on transformFn is always undefined, and the query string stays in the AngularJS format.

You can see this live in jsFiddle too: http://jsfiddle.net/fcoury/QKmnX/

Any idea how I force the query string to use jQuery's $.param format?

EDIT: I was checking AngularJS code for branch v1.0.x and I couldn't find any way to change the Query String construction code, that takes place here:

https://github.com/angular/angular.js/blob/v1.0.x/src/ngResource/resource.js#L299-L306

Does anyone have any clever way to override that part of the ngResource class?

Community
  • 1
  • 1
kolrie
  • 12,562
  • 14
  • 64
  • 98

2 Answers2

1

My simple solution:

module.run(['$http', '$httpParamSerializerJQLike', function($http, $httpParamSerializerJQLike) {
  $http.defaults.paramSerializer = $httpParamSerializerJQLike;
}]);
Oded Niv
  • 2,557
  • 2
  • 22
  • 20
0

Why are you using push? The examples from here just assign:

$httpProvider.defaults.transformRequest = function(data) {...};
Community
  • 1
  • 1
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • I tried both ways, it doesn't work, data is used for the POST (or PUT) data payload, not for query strings. I am checking AngularJS code and I think it's not possible to override how the query string is created. – kolrie Dec 30 '12 at 19:39
  • 1
    Hmm, just saw that I provided a link to an answer to your other question. Sorry about that. Can't you just use $hhtp instead of $resource? – asgoth Dec 30 '12 at 20:27
  • 1
    Yes, I will be using $http for the time being, but would be nice to have this flexibility, I am proposing it here: https://groups.google.com/forum/?fromgroups=#!topic/angular/sXBeosUvSao – kolrie Dec 30 '12 at 21:13