ljharb / qs

A querystring parser with nesting support
BSD 3-Clause "New" or "Revised" License
8.57k stars 731 forks source link

Decoder function not being called #284

Open FredericLatour opened 6 years ago

FredericLatour commented 6 years ago

Hi, I'm getting crazy with this but for some reason the decoder function seems to never be called. Here is my code:

  router.get('/testqs', function(req, res) {
    const result = qs.parse(req.query, {
      decoder: function (str) {
        let result: any
        const keywords: any = {
          true: true,
          false: false,
          null: null,
          undefined: undefined
        }

        if (str in keywords) {
          result = keywords[str]
        } else {
          const parsed = parseFloat(str)
          if (isNaN(parsed)) {
            result = str
          } else {
            result = parsed
          }
        }

        console.log(str, result)
        return result
      }
    })
    res.json(result)
  })

When I send a request:

GET {{host}}{{api}}/testqs?maintYear=2018&maintMonth=5&fields[]=id&fields[]=regname&fields[]=price&notRenewed=true

I get the following result:

{
  "maintYear": "2018",
  "maintMonth": "5",
  "fields": [
    "id",
    "regname",
    "price"
  ],
  "notRenewed": "true"
}

To summarize, evrrything seems to work properly except that the decoder function seems to never be called (and of course, I don't have any console.log output from inside the function).

I noticed that someone in the following comment (https://github.com/ljharb/qs/issues/91#issuecomment-358708095) that someone is saying that this doesn't seem to work for him but not sure if he doesn't like the result or if he encounters the same problem as I do.

Any idea regarding what could go wrong ?

Thanks

FredericLatour commented 6 years ago

ok, my bad. I had to pass the querystring as a string. Something like:

const queryString = req.originalUrl.substr(req.originalUrl.indexOf('?')+1)

That said, qs seems to be able to parse from a dictionary (req.query object). In that case wouldn't this make sense to apply the decoder function as well?

ljharb commented 6 years ago

parse should primarily only be expecting a string; in your case req.query is already parsed (i think you can configure express to use your own qs instance, though).

It's true that parse can accept an object, but in that case it only runs the internal parseKeys function, which doesn't have support for decoder. It'd be reasonable to add this support, though.

FredericLatour commented 6 years ago

@ljharb Indeed, I realized my mistake afterward. I did not realized immediatly because I was getting proper results besides not having the decoder function being executed.
Unless there is some good reasons not to do so, I think that either you should only accept strings or apply the same process when parsing an object.

Yes, it seems that one can get qs feature using body-parser extended mode. However, the documentation is quite slim and I didn't want to fight hours in order to find the proper way to use it. Thanks