FabienHenon/remote-resource/1.0.0

NOTE: the latest version is 1.0.1

Formerly calions-app/remote-resource. Search finds this package by either name.

Rerouted (retagged, needs approval). The tag now points at a different commit than when this version was published. The Lamdera package server serves a copy recovered from https://github.com/FabienHenon/remote-resource.

What we checked: Tag 1.0.0 is still on github.com/FabienHenon/remote-resource; its commit 0fc95f001af0 is from 2021-05-24 16:05 UTC, after the version was published (2019-09-06 10:19 UTC); elm.json differs from package.elm-lang.org's; the exposed modules match docs.json; the zip's SHA-1 is not the published one and nothing else confirms its contents.

We could not verify this copy against what was published, so the Lamdera compiler asks before using it (y/n). Without a terminal, as in CI, it stops with an error unless approved:

  • lamdera make --auto-approve-package-rerouting approves rerouted versions for that run,
  • LAMDERA_AUTO_APPROVE_PACKAGE_REROUTING=1 does the same for every run in that environment,
  • LAMDERA_CACHE=off skips the Lamdera package server altogether: packages come from package.elm-lang.org and GitHub only, as with elm, and a rerouted version then fails to download.

Details · package.elm-lang.org's zip: https://github.com/FabienHenon/remote-resource/zipball/1.0.0/

remote-resource Build Status

Remote Resource alllows you to handle foreground and background resources, using RemoteData.

For instance, let's say you want to retrieve a list of posts. You are using the RemoteData package, thus you can handle the state of your request (Loading, Success, etc...). You will probably display a loading icon while your request is in progress, and once it has been fully retrieved you will display your posts. But now, let's say you know your posts have changed and you would like to update them. You will probably want to send another request to your webservice with the same Elm RemoteData you used when you first retrieved your posts. That means your users will see your posts disapear for a few milliseconds (depending on the latency and network speed), replaced by a loading icon, to be finally updated and displayed again to your users.

Now, with RemoteResource you can refresh your posts in the background. Than means that you keep displaying your "old" posts to your users, and when the new data has been retrieved you can replace your old posts by the new ones without your users seeing some loading icon!

Getting started

Here is an example where you want to retrieve posts. When you receive a refresh event you retrieve the new posts while still showing the old posts to the users. In your view you will display a button when the new posts have been retrieved to let the user replace the old posts by the new ones:

type Msg
    = Refresh
    | OnDataRetrieved (RemoteData Http.Error (List Post))
    | UpdateData

type alias Model =
    { posts : RemoteResource Http.Error (List Post) }


init : (Model, Cmd Msg)
init =
    ( { posts = RemoteResource.init |> RemoteResource.loading }
    , retrievePosts OnDataRetrieved 
    )

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of
        Refresh ->
            ( { model | posts = model.posts |> RemoteData.reloading }
            , retrievePosts OnDataRetrieved
            )

        OnDataRetrived data ->
            ( { model | posts = model.posts |> RemoteData.setBackground data }
            , Cmd.none
            )

        UpdateData ->
            ( { model | posts = model.posts |> RemoteData.replaceResourceByBackground }
            , Cmd.none
            )

view : Model -> Html Msg
view { posts } =
    div []
        [ if RemoteResource.hasNewResource comparePosts posts then
            button [ onClick UpdateData ] [ text "Show my new posts" ]
          else
            text ""
        , case posts of
            NotAsked ->
                loadingIcon

            Loading ->
                loadingIcon

            Failure err ->
                text "Failed"

            Success data ->
                div []
                    (List.map viewPost data)
        ]

subscriptions : Sub Msg
subscriptions =
    onRefresh Refresh

In the example below you will display the number of connected users. When you receive a refresh event you retrieve the new count of connected users and you replace the old count by the new count without showing the loading icon:

type Msg
    = Refresh
    | OnDataRetrieved (RemoteData Http.Error Int)

type alias Model =
    { count : RemoteResource Http.Error Int }


init : (Model, Cmd Msg)
init =
    ( { count = RemoteResource.init |> RemoteResource.loading }
    , retrieveConnectedUsersCount OnDataRetrieved 
    )

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of
        Refresh ->
            ( { model | count = model.count |> RemoteData.reloading }
            , retrieveConnectedUsersCount OnDataRetrieved
            )

        OnDataRetrived data ->
            ( { model | count = model.count |> RemoteData.setResource data }
            , Cmd.none
            )

view : Model -> Html Msg
view { count } =
    div []
        [ case count of
            NotAsked ->
                loadingIcon

            Loading ->
                loadingIcon

            Failure err ->
                text "Failed"

            Success data ->
                div [] [ text ("Connected users: " ++ (String.fromInt data)) ]
        ]

subscriptions : Sub Msg
subscriptions =
    onRefresh Refresh