3

When I have a url like this:

http://server/site?firstname=Jack&lastname=Daniels

I understand that in my JavaScript a query for firstname should return "Jack".

But what should the query for firstname return in the following cases:

http://server/site?lastname=Daniels
http://server/site?firstname&lastname=Daniels
http://server/site?firstname=&lastname=Daniels

[Edit] To answer some of the comments: all of the above are legal querystrings, my question is not about how to retrieve the parameters but how to interpret them.

For the record, I parse querystrings with the following regular expression that covers all cases:

/([^?=&;]+)(?:=([^&;]*))?/g

Apparently there's a very popular question on how to retrieve querystring parameters, but the answer is incorrect (or at least not addressing edge cases).

[Update] My choice based on the answers from @Bergi and @zzzzBov:

http://server/site?lastname=Daniels                => firstname: undefined
http://server/site?firstname&lastname=Daniels      => firstname: true
http://server/site?firstname=&lastname=Daniels     => firstname: ""
http://server/site?firstname=Jack&lastname=Daniels => firstname: "Jack"

A side effect is that I had to slightly modify my regex, as with the above rules the = sign needs to be captured:

/([^?=&;]+)(=[^&;]*)?/g
Community
  • 1
  • 1
Christophe
  • 27,383
  • 28
  • 97
  • 140
  • Get the query string data and meanwhile you can ignore the not valid query string parameters and show result set with the valid parameters – Srinivas Reddy Thatiparthy Feb 11 '13 at 18:07
  • Personally, I always this use function: http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values – Dom Feb 11 '13 at 18:10

2 Answers2

1

But what should the query for firstname return in the following cases:

http://server/site?lastname=Daniels
http://server/site?firstname&lastname=Daniels
http://server/site?firstname=&lastname=Daniels

Query strings can easily be represented by object notation in JavaScript. Simply set only the keys that are present in the query string on the object.

This means that for ?lastname=Daniels the object produced should be:

{
    lastname: 'Daniels'
}

In cases where the key is present, but no value is given (no equals sign), the key should be set with a value of null which represents "no value".

This means that for ?firstname&lastname=Daniels the object produced should be:

{
    firstname: null,
    lastname: 'Daniels'
}

In cases where the key is present, and the value provided is empty (equals sign), the value is actually the empty string.

This means that for ?firstname=&lastname=Daniels the object produced should be:

{
    firstname: '',
    lastname: 'Daniels'
}

There is also an often overlooked case of where the same key is used multiple times. In the traditional query-string syntax (not PHP), keys can be used multiple times, as-is, to represent an array.

This means that for ?foo=bar&foo=baz the object produced should be:

{
    foo: [
        'bar',
        'baz'
    ]
}

<aside>

In PHP land, keys used for arrays are suffixed with []:

`?foo[]=bar&foo[]=baz`

PHP will automatically convert the query-string server side such that:

$_GET['foo'] = array('bar', 'baz')

</aside>

Going back to the original question, what this implies is the following:

  • ?lastname=Daniels has a value of undefined for the firstname key.
  • ?firstname&lastname=Daniels has a value of null for the firstname key.
  • ?firstname=&lastname=Daniels has a value of '' for the firstname key.

For cases where a key is used as a boolean based on its presence, you should be checking whether the object has the key set (and completely ignore the value, as it doesn't matter).

Typically this is done with obj.hasOwnProperty('key'), however as the object is really more of a hash, Object.prototype.hasOwnProperty.call(obj, 'key') is preferrable, which could be abstracted into a has function:

has(obj, key) {
    return Object.prototype.hasOwnProperty.call(obj, key);
}

If you're using underscore.js, then you could use _.has(obj, key)

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • 1
    @Christophe, Bergi makes a good point about the use of boolean keys, however if you're using an object representation of a query-string you should be using `obj.hasOwnProperty('key')` to check if the key exists in the object. Actually, even that's wrong, [you should *really* be using something like `has(obj, 'key')`](http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/). – zzzzBov Feb 11 '13 at 19:43
0

But what should the query return

That's your decision, what do you need? There are several querystring-evaluating functions of different complexity. Some of them can deal with repeated, nested, bracket-syntax values, others not. Famous ones can be found in How can I get query string values in JavaScript? and its duplicate questions.

However, you asked for conventions:

http://server/site?lastname=Daniels

The result should be something falsy to represent the absence of firstName. You might choose null or undefined.

http://server/site?firstname&lastname=Daniels

This often represents some boolean parameter, so returning true would be legitimate. Yet I'm sure there are libs that completely ignore this format.

http://server/site?firstname=&lastname=Daniels

That's quite obviously the empty string "".

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thx! I didn't think about returning true for the second case. Would you have a reference that shows it's standard? – Christophe Feb 11 '13 at 18:35
  • Since none of these functions are standardized, there hardly will be a reference. Of course you might have a look at URL-parsing-functions' documentations in popular js libraries. – Bergi Feb 11 '13 at 18:40
  • Marked this one as answer and I really like the idea of setting the parameter to true in case 2. However as I said in my updated post the reference doesn't look right. – Christophe Feb 11 '13 at 22:53