> Put another way, *Elm does not have anything similar to components!*
> But how about elm-mdl, elm-autocomplete, elm-ui, elm-datepicker, 
> elm-form, elm-sortable-table even spinner elm-spinner? Thay all use theirs 
>  model, update, view "triplet" to be reusable and hide implementation 
> details.
And it is differently similar to components and pretty abstracted and 
> reusable. 

In libraries that have component systems, components are used as a common 
building block. They're encouraged as a good default choice, a method of 
reuse to reach for as a matter of course.

When making something reusable in Elm, we always want to start with data if 
we can get away with it. If we can't get away with data, then we use a 
function. If a function still won't do the trick, we try upgrading it to a 
higher-order function. Only after all else fails do we resort to 
encapsulating a separate model, update, and view. It's the most expensive 
way to reuse anything, not something we should reach for as a matter of 

That's the difference. Components are something you use at the drop of a 
hat. In Elm, encapsulated state is something you use when you tried all the 
simpler ways to reuse something first, and none of them worked out.

Hence my objection to *"I know that Elm doesn't have the concept of 
components but instead it has triplets."*

What I'd say instead is *"I know Elm doesn't have the concept of components 
but instead it discourages encapsulating state except as a last resort." *

Like Evan said, "it just works different in Elm. We do not think in terms 
of reusable components." :)

This "not component" will be used here only once (or more but not now) but 
> should be used in several similar projects.They all will be using the same 
> Identity Service so userInfo(and login/logout) should look and feel similar.

That greatly clarifies things, thank you!

Since this is going to be used in multiple projects, it will want to be a 
separate package. I would look at thebritician/elm-autocomplete 
as a starting point.

I'd give UserInfo its own model, view, and update (since it is clearly 
doing a bunch of complicated state logic, all of which needs to be 
reusable) and expose a UserInfo.update function like this:

update : Maybe User -> UserInfo.Msg -> UserInfo.State -> ( UserInfo.State, 
Cmd UserInfo.Msg, Maybe User )

The idea is that the caller is responsible for storing the logged-in (or 
not, hence the Maybe) user - we don't store that user inside UserInfo.State. 
If the user logs in, we inform the caller by passing Just loggedInUser as 
the third element in the tuple we return. If the user logged out, we return 
Nothing. If neither happened, we return untouched whatever user the caller 
passed us. Regardless, it's up to the caller to store that information.

So the caller's update might look something like this:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        UserInfoMsg subMsg ->
                ( userInfoState, subCmd, user ) =
                    UserInfo.update model.user subMsg model.userInfoState
                ( { model | userInfoState = userInfoState, user = user }
                , Cmd.map UserInfoMsg subCmd

Similarly, this would mean UserInfo.view would take the user separately as 
well, which the caller would be responsible for passing in:

view : Maybe User -> UserInfo.State -> Html UserInfo.Msg

Hope that helps!

You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to