2
\$\begingroup\$

I'm handling parameters that are passed from a URL. I want to keep my URLS neat, and the following (rather exhaustive code) has been able to achieve it.

There will be more added, so it would be good to keep it versatile and compact. Code below does work.

URLS patterns

a.com/

a.com/q=bar

a.com/filters=foo

a.com/q=bar&filters=foo

Current code to account for above

const isSearch = this.props.location.pathname.includes("q=")
const isFilter = this.props.location.pathname.includes("filters=")

const encodedVal = encodeURIComponent(e.target.value)

if (encodedVal && isSearch && isFilter) {
    const filters = this.props.match.params.q.split("filters=")[1].split("&")[0];
    this.props.history.push("/q=" + encodedVal + "&filters=" + filters );
  }
 else if (encodedVal && isFilter) {
    const filters = this.props.match.params.q.split("filters=")[1].split("&")[0];
    this.props.history.push("/q=" + encodedVal + "&filters=" + filters );
  }
 else if (encodedVal && isSearch) {
    this.props.history.push("/q=" + encodedVal);
  }
 else if (isFilter && !encodedVal) {
    const filters = this.props.match.params.q.split("filters=")[1].split("&")[0];
    this.props.history.push("/filters="  + filters);
  }
 else if (encodedVal) {
    this.props.history.push("/q=" + encodedVal);
  }
  else {
    this.props.history.push("/");
  }
\$\endgroup\$
3
  • \$\begingroup\$ Why not URLSearchParams and the standard ?-query URL instead? \$\endgroup\$ Commented Aug 1, 2017 at 15:51
  • \$\begingroup\$ Could you show an example of how I would use it? \$\endgroup\$ Commented Aug 1, 2017 at 16:35
  • \$\begingroup\$ Also, URLSearchParams don't seem to be compatible with mobile browsers as per the docs you linked. \$\endgroup\$ Commented Aug 2, 2017 at 3:43

1 Answer 1

1
\$\begingroup\$

Fragile parsing of query parameters

For example, the implementation will silently convert a url like /bbq=grill&pagefilter=foo into /q=grill&filter=foo.

Inappropriate use of query parameters

The example urls use some sort of illegal form of query parameters. Query parameters should come after ? in a url. (The part of a url after ? is called the query string.)

Unclear purpose

It seems that encodedVal is the encoded value of q=. If that's the case, it's not clear from the posted code. If that's not the case, then the posted code ignored the value of q=, and it's not clear why.

On the other hand, the value of filter= is left untouched.

Why not encode all the query values? It's puzzling.

Complicated parsing of query parameters

The chain of conditions is complicated, fragile, and it won't scale if you need to add something else later. It's hard to understand and to modify.

It would be better to properly tokenize the query parameters into key-value pairs (so an object in JavaScript). Let's call this object query. Then, the implementation to build the url fragment can be written a simple straightforward way that's easy to understand and to extend.

var encodedUrl = "";

if (query.q) {
    encodedUrl += "&q=" + encodeURIComponent(query.q);
}

if (query.filters) {
    encodedUrl += "&filters=" + encodeURIComponent(query.filters);
}

// chop off any excess leading "&"
if (encodedUrl) {
    encodedUrl.substr(1);
}

// let's make this a proper query string
this.props.history.push("?" + encodedUrl);
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for that. Both q and filter are independent functions. They occur with an onChange or onClick. Could you give an example of tokenizing the query parameres into key-value pairs? I don't know what to define query as.` encodedVal` is what I used initially \$\endgroup\$ Commented Aug 4, 2017 at 2:34
  • \$\begingroup\$ Oh, and filter is an array ["foo", "bar"], q is a string \$\endgroup\$ Commented Aug 4, 2017 at 3:43
  • \$\begingroup\$ @Ycon One way to parse the query string is to scan from the beginning, reading a key until a = and then a value until either you reach the end or a & that is not the first character of a & (not an embedded & in the value, but a real separator). Continue reading the rest of the query string until you reach the end, populating an object of key-value pairs as you go \$\endgroup\$ Commented Aug 4, 2017 at 5:56

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.