DEV Community

Richard Wood for ElmUpdate

Posted on • Edited on

Geolocation in an Elm web application

Getting location for your web application comes down to basing it on an IP address or using the HTML5 geolocation provided through your browser.

In the IP address case the location information may come from the registration addresses of the IP addresses amongst other sources.

With the browser approach it will depend whether your device has GPS or not. If so then it can use that system, otherwise it may also look up third party databases of IP addresses. One example is the data collected by Google's StreetView surveys.

Getting IP address sourced location data using Elm is easy-as. First find a source by googling for IP address location data. I found this list to be very useful: (https://ahmadawais.com/best-api-geolocating-an-ip-address/)

Then you want to send off an Http.get request. For example:

Set up the get, where decodeData uses the original method or the pipeline decoder style and YourData is a type alias reflecting the format of the data.

getData = 
    Http.get "https://api.ipdata.co/?format=json" decodeData

decodeData =
    decode YourData
        |> required "latitude" Json.Decode.float
        |> required "longitude" Json.Decode.float

Do the send using the Http.send or RemoteData.send approach. In this case LoadData is a Msg (Result Http.Error YourData) you've defined to handle the response.

sendData =
    Http.send LoadData getData

If you want to use the HTML5 solution built into your browser then there is an Elm module for that - Geolocation.elm -http://package.elm-lang.org/packages/elm-lang/geolocation/1.0.2/Geolocation

In the simplest case you may fire off the Cmd msg from an Update function where FoundLocation will be another update function that interprets the results:

GetLocation ->  
            ( model, Task.attempt FoundLocation Geolocation.now )

FoundLocation -> 
    case location of
           Err error ->
               ... do a case match on the various error types

           Ok location ->
               ... access location.latitude, location.longitude and any other data you need

Note the user will be asked to confirm that it is okay to share location information.

You may also want your app to be told when the user moves. You can set up an Elm subscription, which will call a specified update function - eg MoveLocation - when there is a change, with a Location type parameter.

subscriptions : Location -> Sub Msg
subscriptions location =
    Sub.batch
        [ Geolocation.changes MoveLocation ]

Whether you need to store state on your model will depend on your application. If so then at the beginning you won't know location so you will need to store location as a Maybe field and incorporate handling for this.

Top comments (1)

Collapse
 
jonathankosgei profile image
Jonathan Kosgei

Hey Richard, I wrote this more detailed comparison of IP Geolocation APIs - Comparing 8 Commercial IP Geolocation APIs. Let me know if it helps! :-)