How to pass ampersand (&) to AngularJS resource parameter

2.6k views Asked by At

I have an angular resource declared as follows

angular.module('xpto', ['ngResource'])
.factory('XPTO', function ($resource, $location) {
    var XPTO = $resource($location.protocol() + '://' + $location.host() +
    ':port' + '/myservice.svc/gerencia?sigla=:sigla',
        {
            port: ':' + $location.port()
        }
    );
    return XPTO;
})

and I would like to call the service passaing a parameter that contains an ampersand (&), something like:

XPTO.query({ sigla: 'abc&d' }, function (gerencias) {
$scope.gerenciasBuscadas = gerencias;
});

However, AngularJS does not encode the & properly. It sends "sigla=abc&d" instead of "sigla=abc%26d" , causing my server to see the query string parameter value for "sigla" as being just "abc", instead of "abc&d".

Looking into angular-resource-1.0.7.js, I saw the following:

/**
 * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
 * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
 * segments:
 *    segment       = *pchar
 *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
 *    pct-encoded   = "%" HEXDIG HEXDIG
 *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
 *                     / "*" / "+" / "," / ";" / "="
 */
function encodeUriSegment(val) {
  return encodeUriQuery(val, true).
    replace(/%26/gi, '&').
    replace(/%3D/gi, '=').
    replace(/%2B/gi, '+');
}

So, it will encode '&' and decode it back before it sends the request to the server. Is there any point where I could customize the url right before it is sent to the server? Changing encodeUriSegment is an option, but it might break other stuff inside Angular. Any ideas?

1

There are 1 answers

0
alediaferia On BEST ANSWER

This is a bug in AngularJS.

I posted a pull request for fixing this. You can help me getting it merged commenting on the pull request itself here.