Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get window.location.href in Elm?

I have an index.html which contains my Elm app. The Elm app uses various GETs to an API served by the same server as the one that serves the index.html.

Rather than hardcode the URLs in my Elm code for the GETs, e.g.:

url =
    "http://localhost:8080/api/tasks"

is there a function which returns the value of window.location.href?

I'd like to do something like:

url =
    getHref() ++ "/api/tasks"

In this way, if I move my server to somewhere else I will not need to update all the urls in my Elm code.

like image 722
Robert Avatar asked Aug 03 '18 00:08

Robert


3 Answers

Whilst the above answers your question, I think there is a more straightforward solution to the problem:

If the application code is being served from the same server (URL) as the API you want to access you don't need to specify the server - just the root relative path for your api i.e. you can make requests to /api/tasks from your elm code and the browser will sort out the rest for you.

This is how I addressed the problem in my deployed code.

like image 102
Murph Avatar answered Oct 04 '22 04:10

Murph


There is elm-history package with the location function for this, but it's deprecated and doesn't exist for 0.18 version.

Then you might want to use elm-navigation package and explicitly store the current location in your model.

Please have a look at this example. A program with navigation can be created via:

Navigation.program UrlChange
    { init = init
    , view = view
    , update = update
    , subscriptions = (\_ -> Sub.none)
    }

UrlChange here is a type of message, which triggers on every url change, so you can process it and set the current location:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        UrlChange location ->
            ( { model | location = location }
            , Cmd.none
            )

And then purely get the location.href wherever the model is accessible.

In the provided application, this place is view: viewLocation model.location

In your application, it's, for example, something like this:

url model =
    model.location.href ++ "/api/tasks"
like image 28
Igor Drozdov Avatar answered Oct 04 '22 04:10

Igor Drozdov


Use URL Builder to link to anoter page on your site

There's no need to specify the base url:

import Url.Builder exposing (absolute)
url = absolute [ "api", "tasks" ] []
-- results in "http://localhost:8080/api/tasks"
-- if working in your developer environment
-- the URL will automatically change in production
-- to the correct URL assuming you don't have any crazy set ups

And you definitely will not need to worry if your server URL changes. So you can easily switch from a development to production/staging environments without any additional configuration.

like image 22
BenKoshy Avatar answered Oct 04 '22 04:10

BenKoshy