Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

evancz/url-parser and multiple query parameters

Tags:

elm

I'm not sure how to get access to multiple query parameters.

There is no example in the source code for that.

I know how to get one query parameter using <?>:

routeParser : Url.Parser (Route -> a) a
routeParser =
    Url.oneOf
        [ Url.map HomeRoute Url.top
        , Url.map SettingsRoute (Url.s "settings" <?> Url.stringParam "sortBy")
        ]


parseLocation : Location -> Route
parseLocation location =
    location
        |> Url.parsePath routeParser
        |> Maybe.withDefault NotFoundRoute

With parsePath I can get Dict with query params, but Is there an elegant way using <?>?

Edit:

I've used this example in elm-repl:

> parsePath (s "blog" <?> stringParam "search" <?> stringParam "sortBy") (Location "" "" "" "" "" "" "/blog" "?search=cats&sortBy=name" "" "" "")
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The 1st argument to function `parsePath` is causing a mismatch.

5|   parsePath (s "blog" <?> stringParam "search" <?> stringParam "sortBy") (Location "" "" "" "" "" "" "/blog" "?search=cats&sortBy=name" "" "" "")
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Function `parsePath` is expecting the 1st argument to be:

    Parser (Maybe String -> Maybe String) (Maybe String)

But it is:

    Parser (Maybe String -> Maybe String -> Maybe String) (Maybe String)

Hint: It looks like a function needs 1 more argument.
like image 665
rofrol Avatar asked Mar 30 '17 07:03

rofrol


1 Answers

You can chain <?> together for multiple query parameters. Let's say your SettingsRoute also expected a pageNumber integer argument:

type Route
    = ...
    | SettingsRoute (Maybe String) (Maybe Int)

Your parser could then look like this:

Url.map SettingsRoute (Url.s "settings" <?> Url.stringParam "sortBy" <?> Url.intParam "pageNumber")

The query parameters from the incoming URL don't need to be in the same order as your map statement. The following example will give the same results for the above route:

settings?sortBy=name&pageNumber=3
settings?pageNumber=3&sortBy=name

Edit

You added an example from the REPL. The problem you are experiencing in the REPL is because you aren't mapping correctly to something that takes two parameters. Consider this example for the REPL:

> type alias SearchParams = { search : Maybe String, sortBy : Maybe String }
> parsePath (map SearchParams (s "blog" <?> stringParam "search" <?> stringParam "sortBy")) (Location "" "" "" "" "" "" "/blog" "?search=cats&sortBy=name" "" "" "")
Just { search = Just "cats", sortBy = Just "name" }
    : Maybe.Maybe Repl.SearchParams
like image 72
Chad Gilbert Avatar answered Oct 07 '22 12:10

Chad Gilbert