How can I get window.location.href in Elm?
Asked Answered
W

3

10

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.

Whipsaw answered 3/8, 2018 at 0:0 Comment(0)
M
6

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"
Morganmorgana answered 3/8, 2018 at 3:2 Comment(1)
This answer is out of date now. The new module is elm/browser. The problem with that module is that it forces you to switch from Program to Browser, which is a much bigger change.Leptorrhine
T
8

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.

Tuque answered 3/8, 2018 at 15:6 Comment(0)
M
6

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"
Morganmorgana answered 3/8, 2018 at 3:2 Comment(1)
This answer is out of date now. The new module is elm/browser. The problem with that module is that it forces you to switch from Program to Browser, which is a much bigger change.Leptorrhine
H
4

Use URL Builder to link to another 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.

Hackberry answered 1/12, 2020 at 2:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.