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?

2
  • Nice question. I think you could take Ivo's suggestion and put it here as an answer. Commented Nov 8, 2013 at 6:26
  • @Ramunas where is ivo's suggestion? Commented Jan 21, 2017 at 11:21

2 Answers 2

1

My simple solution:

module.run(['$http', '$httpParamSerializerJQLike', function($http, $httpParamSerializerJQLike) {
  $http.defaults.paramSerializer = $httpParamSerializerJQLike;
}]);
Sign up to request clarification or add additional context in comments.

Comments

0

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

$httpProvider.defaults.transformRequest = function(data) {...};

3 Comments

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.
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?
Yes, I will be using $http for the time being, but would be nice to have this flexibility, I am proposing it here: groups.google.com/forum/?fromgroups=#!topic/angular/sXBeosUvSao

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.