Node.js - Array is converted to object when sent in HTTP GET request query

Related searches

The following Node.js code:

var request = require('request');

var getLibs = function() {
    var options = { packages: ['example1', 'example2', 'example3'], os: 'linux', pack_type: 'npm' }

    request({url:'http://localhost:3000/package', qs:options}, 
    function (error , response, body) {
        if (! error && response.statusCode == 200) {
            console.log(body);
        } else if (error) {
            console.log(error);
        } else{
            console.log(response.statusCode);
        }
    });
}();

sends the following http GET request query that is received by like this:

{"packages"=>{"0"=>"example1", "1"=>"example2", "2"=>"example3"}, "os"=>"linux", "pack_type"=>"npm"}

How can I optimize this request to be received like this:

{"packages"=>["example1", "example2", "example3"], "os"=>"linux", "pack_type"=>"npm"}

Note. The REST API is built in Ruby on Rails

If the array need to be received as it is, you can set useQuerystring as true:

UPDATE: list key in the following code example has been changed to 'list[]', so that OP's ruby backend can successfully parse the array.

Here is example code:

const request = require('request');

let data = {
  'name': 'John',
  'list[]': ['XXX', 'YYY', 'ZZZ']
};

request({
  url: 'https://requestb.in/1fg1v0i1',
  qs: data,
  useQuerystring: true
}, function(err, res, body) {
  // ...
});

In this way, when the HTTP GET request is sent, the query parameters would be:

?name=John&list[]=XXX&list[]=YYY&list[]=ZZZ

and the list field would be parsed as ['XXX', 'YYY', 'ZZZ']


Without useQuerystring (default value as false), the query parameters would be:

?name=John&list[][0]=XXX&list[][1]=YYY&list[][2]=ZZZ

Node.js – Passing Arrays in the Querystring, One of the enticing attributes of Node.js development is the high level page, and can be a useful way to send static arguments to a web page. The most effective, all-around solution is to encode the object or array into a JSON string, application will need to convert the input Querystring into an object. In Node.js, functionality to aid in the accessing of URL query string parameters is built into the standard library. The built-in url.parse method takes care of most of the heavy lifting for us. Here is an example script using this handy function and an explanation on how it works:

I finally found a fix. I used 'qs' to stringify 'options' with {arrayFormat : 'brackets'} and then concatinated to url ended with '?' as follows:

var request = require('request');
var qs1 = require('qs');

var getLibs = function() {
    var options = qs1.stringify({ 
        packages: ['example1', 'example2', 'example3'], 
        os: 'linux', 
        pack_type: 'npm' 
        },{
        arrayFormat : 'brackets'
    });


    request({url:'http://localhost:3000/package?' + options}, 
    function (error , response, body) {
        if (! error && response.statusCode == 200) {
            console.log(body);
        } else if (error) {
            console.log(error);
        } else{
            console.log(response.statusCode);
        }
    });
}();

Note: I tried to avoid concatenation to url, but all responses had code 400

Query string, Domain � ECMAScript modules � Errors � Events � File system � Globals � HTTP � HTTP/2 The querystring.parse() method parses a URL query string ( str ) into a The object returned by the querystring.parse() method does not prototypically converting URL-unsafe characters to percent-encoding in the query string. This guide outlines how to use the HTTP Request object to read request data. The Node.js raw req object can be accessed via request.request . AdonisJs passes the current HTTP request object as part of the HTTP Context which is sent to all route handlers and middleware:

This problem can be solved using Request library itself. Request internally uses qs.stringify. You can pass q option to request which it will use to parse array params.

You don't need to append to url which leaves reader in question why that would have been done.

Reference: https://github.com/request/request#requestoptions-callback

const options = {
  method: 'GET',
  uri: 'http://localhost:3000/package',
  qs: {
    packages: ['example1', 'example2', 'example3'], 
    os: 'linux', 
    pack_type: 'npm' 
  },
  qsStringifyOptions: {
    arrayFormat: 'repeat' // You could use one of indices|brackets|repeat
  },
  json: true
};

Long Arrays converted to Objects � Issue #289 � expressjs/body , add a long array to a query string the body parser converts it to an Object. var bodyParser = require('body-parser') var express = require('express') so normal behavior will get the arrays they expect up to any length When sending your request, just remove indexes from your query string, like that => The same way there is no concensus over how objects should be represented in query parameters, there is no standardized way to format arrays of values in query parameters. There may be several…

Limited query string parsing in express, bug or feature?, Also, when parsing arrays qs package parses only 20, any array with members greater than 20 would be converted to an object with indexes as keys. When making HTTP request, data can be sent via POST message body, or via and reusing links, GET requests with query strings are more applicable. Once you get started with it and you love it then you will face the problem of sending Array parameters with your GET or POST request. Postman allows anyone to send any kind of array with their

Get Query Strings and Parameters in Express.js, It is meant to send small amounts of information to the server via the url. This is a pretty common use-case in Express, and any HTTP server, so hopefully Your query parameters can be retrieved from the query object on the request object� While query parameters are typically used in GET requests, it's still possible to see them in POST and DELETE requests, among others. Your query parameters can be retrieved from the query object on the request object sent to your route. It is in the form of an object in which you can directly access the query parameters you care about.

The Angular Http client communicates with the server using a familiar HTTP request/response protocol. The Http client is one of a family of services in the Angular HTTP library. When importing from the @angular/http module, SystemJS knows how to load services from the Angular HTTP library because the systemjs.config.js file maps to that module

Comments
  • I think it's expected behavior. How else would you implement sending array over get request in query param? Usually, it's sent as ?id[]=uuid1&id[]=uuid2
  • I have already succeeded to send the query in the desired format using Ruby. So why the change in request format between Ruby and Node.js? And how to stop it from occurring?
  • The query was received like you mentioned : ?packages=example1&packages=example2&packages=example3..... but not parsed as an array. instead it became {"packages"=>"uuid", "os"=>"linux", "pack_type"=>"npm"}
  • The query in my Ruby code was sent as: ?packages[]=example1&packages[]=example2&packages[]=example3..... Then parsed to: {packages = ['example1', 'example2', 'example3'], ......}
  • @TamerB Then you can use packages[] as the key of data. I've edited the answer.
  • This will send "packages" as an array with one object inside it. i.e. The request will be like this: {"packages"=>[{"0"=>"example1","1"=>"example2","2"=>"example3"}]....}. Any way, I finally found an idea that solved my problem. Please find my answer. Thank you for your effort :)
  • Thanks @TamerB but I'm a bit confused. You mentioned in the Ruby code (which works) the query is ?packages[]=xxx&packages[]=yyy&packages[]=zzz. But that is exact what useQuerystring: true do. Very weird...