Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top