I’ve written an interface for our website search. It handles things like filtering, sorting, etc. and refreshing the results as those things change.
I’m using the URL as the source-of-record for the initial state of the search interface (I pass the current URL in via a flag). As the filters, sorting, etc. are updated, I modify the URL and, via a port, use pushState to update the current URL. This means that users can bookmark a search results page, share by copying the url, etc. It’s working pretty well. I load state by parsing a URL and I store state by encoding a URL.
The problem I’m running into is with spaces in the search string. A search starts with a regular HTML form that does a GET request to the search page. If someone searches for “foo bar”, then the URL looks like
http://www.example.com/search?q=foo+bar. The problem is that after I parse out the
q param, the string I get back is “foo+bar”. The space remains as a plus and doesn’t get decoded.
Here’s how I’m decoding:
extractSearchStringFromUrl : Url -> Maybe String extractSearchStringFromUrl url = let parser = s "search" <?> Query.string "q" in case Url.Parser.parse parser url of Nothing -> Nothing Just match -> match
Ignore that this case is a little verbose (and unnecessary). It’s going to do some other things in the future.
My question is how can I get a decoded querystring parameter where the pluses are replaced with actual spaces? A plus is a valid character in our search system, so I can’t replace pluses with a space after the match. I did have some success changing
%20 in the URL before I parse it, but that feels clumsy. I’m assuming that there’s a better way to do what I’m doing where I won’t run into the friction I’m running into. Getting decoded strings from a querystring is a well-worn path. Does anyone have any ideas of the best way to do this?
Thanks in advance.