0
votes

I'm trying to do a HTTP GET call using Angular's $http. I've written a generic function like this,

function doGETRequest(url, params) {
      return $http({
        method: 'GET',
        url: baseURL + url,
        headers: {
          'Authorization': 'Bearer ' + access_token
        },
        params: params
      });
    }

I want to create a URL like this, https://content.googleapis.com/drive/v2/about?fields=quotaBytesTotal%2CquotaBytesUsed%2CrootFolderId%2Cuser but I cannot for the life of me figure out the query param part. So far I tried the following:

 doGETRequest('/about', {fields:'user,quotaBytesTotal,quotaBytesUsed,rootFolderId'})


doGETRequest('/about', {fields:['user','quotaBytesTotal','quotaBytesUsed','rootFolderId']})


doGETRequest('/about', {fields:encodeURIComponent('user,quotaBytesTotal,quotaBytesUsed,rootFolderId')})

It does work for the second one, but it parses it as https://content.googleapis.com/drive/v2/about?fields=user&fields=quotaBytesTotal&fields=quotaBytesUsed&fields=rootFolderId and Google just sends response for the first query and ignores the rest (as expected).

So the question is how do I pass comma separated values in query params? Do I have to manually write URL encoded values? Doesn't this beat the purpose of having a params field?

1
the second one should work, it should be handled in the web-serviceJairo Malanay
Web-Service handler in question is Google, so...Any other ideas?PsyGik
sorry, can you post what is your expected url ?Jairo Malanay
It's in the question, but here you go: content.googleapis.com/drive/v2/…PsyGik
you mean the 1st one didnt work ? ( i think that should work ) another way is just change the url: baseURL +'&'+ params -> params = 'fields=quotaBytesTotal,quotaBytesUsed,rootFolderId,user'Jairo Malanay

1 Answers

0
votes

Okay, for those who stumbled upon the same problem as I did, I found two ways of solving this.

First, as @kiro112 suggested in the comments, I write the params directly in the URL. Since $http doesn't encode the URL it'll work. So the code will be something like

doGETRequest('/about?fields='+encodeURIComponent("user,quotaBytesTotal,quotaBytesUsed,rootFolderId"))

and we'll have to get rid of the params part in the doGetRequest() method. Personally, I don't like this one as it beats the purpose of having the params part in $http.

Second method is overriding the default $httpParamSerializer and supplying our own. To do that, the doGetRequest() method has to be modified like so,

function doGETRequest(url, params) {
      return $http({
        method: 'GET',
        url: baseURL + url,
        headers: {
          'Authorization': 'Bearer ' +access_token
        },
        params: params,
        paramSerializer: function (value){
          return Object.keys(value)+'='+encodeURIComponent(Object.values(value));
        }
      });
    }

What happens here is, we do not let angular encode the params. Let me tell you why. As per the docs here, angular only does encoding like so,

  • {'foo': 'bar'} results in foo=bar
  • {'foo': Date.now()} results in foo=2015-04-01T09%3A50%3A49.262Z (toISOString() and encoded representation of a Date object)
  • {'foo': ['bar', 'baz']} results in foo=bar&foo=baz (repeated key for each array element)
  • {'foo': {'bar':'baz'}} results in foo=%7B%22bar%22%3A%22baz%22%7D" (stringified and encoded representation of an object)

Whereas we require something in the lines of {'foo':['bar', 'baz']} resulting in foo=bar%2Cbaz. So we override the paramSerializer and write our own serializer.

The second approach looks much cleaner to me as far as using generic methods is concerned. However, I am still on a look out for a better option.