3

express uses the qs module to parse query strings but it seems to send everything as a string.
How do I get number and boolean values?

app?flag=true&count=20

// => in express gives:

req.query.count === "20"
req.query.flag === "true"

// => whereas I want
req.query.count === 20   // number (int)
req.query.flag === true  // boolean


both of those query params get parsed as strings, which is really annoying to have to do all my own typechecking, parseInt etc. and casting. Is there perhaps a lib that would take care of the resulting object?

Other qs libraries seem to also eschew this simple case although they're great at deeply nested objects encoded on the URL...

https://www.npmjs.com/package/query-string

queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
//=> {foo: ['1', '2', '3']}

Multiple types in query string in nodejs req.params.number is string in expressjs? https://github.com/cdeutsch/query-string-for-all https://www.npmjs.com/package/url-parse

Hasib Samad
  • 1,081
  • 1
  • 20
  • 39
dcsan
  • 11,333
  • 15
  • 77
  • 118
  • Just parse them as you know what you expect for example `parseInt(req.query.count, 10)` – michelem Jun 30 '20 at 10:15
  • 1
    that's exactly what I'm trying to avoid :D, it seems like I must be reinventing the wheel and there's lots of edge cases i could see (ints inside arrays etc) – dcsan Jun 30 '20 at 10:37

1 Answers1

0

It seems you have to write you own decoder option for the parse function, it goes as:

qs.parse(request.querystring, {
      decoder(str, decoder, charset) {
            const strWithoutPlus = str.replace(/\+/g, ' ');
            if (charset === 'iso-8859-1') {
              // unescape never throws, no try...catch needed:
              return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
            }

            if (/^(\d+|\d*\.\d+)$/.test(str)) {
              return parseFloat(str)
            }

            const keywords = {
              true: true,
              false: false,
              null: null,
              undefined,
            }
            if (str in keywords) {
              return keywords[str]
            }

            // utf-8
            try {
              return decodeURIComponent(strWithoutPlus);
            } catch (e) {
              return strWithoutPlus;
            }
          }
})

the credit source: https://github.com/ljharb/qs/issues/91#issuecomment-437926409

blankdeng
  • 63
  • 9
  • I already have a query object, so I think it could be a simpler to just parse the values and not the basic string... – dcsan Jun 30 '20 at 10:39