Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-22 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, March 21, 2017 at 10:57:43 PM UTC, Mark Hamburg wrote:
>
> We've done that as well in places. But I was mostly looking for an example 
> of how to access extra data during an update. 
>
> On Tue, Mar 21, 2017 at 3:20 PM, 'Rupert Smith' via Elm Discuss <
> elm-d...@googlegroups.com > wrote:
>
>> Why not use a secure cookie? Then the browser adds it to the request for 
>> you. It is also more secure and has the advantage that if the user 
>> CTRL+clicks a link in your application opening up the same application in 
>> >1 tab, that the cookies flow across automatically.
>>
>
The reason I pointed this out is that the auth module is one that is likely 
to be needed from a lot of places, so is likely to be at the heart of the 
dependency graph of an application. For that reason, I decided to treat it 
differently.

At first I set up ports so that any module importing Auth could directly 
pass it login/logout/refresh/unauthed requests. Then I changed it to use 
messaging implemented as an effects 
manager: https://github.com/rupertlssmith/elmq.

I only did this for my Auth module, although it could be done for any 
inter-module communication. Really helped to simplify the dependency matrix.

-- 
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.


Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Mark Hamburg
We've done that as well in places. But I was mostly looking for an example
of how to access extra data during an update. Another example from our
codebase is accessing the User record (name, email address, etc) which we
store at the top of the session model. The updater for a more specific
state can send an out message up the stack to get the user record for use
in the update without needing to store a copy of the data in the state or
plumb through passing it down everywhere. That said, it isn't clear how
that plumbing compares to the out message plumbing which is not
insubstantial. But using out messages to retrieve values does avoid having
huge and seemingly haphazard parameter lists.

Mark

On Tue, Mar 21, 2017 at 3:20 PM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> On Tuesday, March 21, 2017 at 6:27:01 PM UTC, Mark Hamburg wrote:
>>
>> P.P.S. If you want your mind more deeply twisted, here is what we do when
>> we want to store the auth token fairly high up but a piece of code needs it
>> for constructing an HTTP request:
>>
>
> Why not use a secure cookie? Then the browser adds it to the request for
> you. It is also more secure and has the advantage that if the user
> CTRL+clicks a link in your application opening up the same application in
> >1 tab, that the cookies flow across automatically.
>
> --
> 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.
>

-- 
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.


Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, March 21, 2017 at 6:27:01 PM UTC, Mark Hamburg wrote:
>
> P.P.S. If you want your mind more deeply twisted, here is what we do when 
> we want to store the auth token fairly high up but a piece of code needs it 
> for constructing an HTTP request:
>

Why not use a secure cookie? Then the browser adds it to the request for 
you. It is also more secure and has the advantage that if the user 
CTRL+clicks a link in your application opening up the same application in 
>1 tab, that the cookies flow across automatically.

-- 
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.


Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Mark Hamburg
And if we were more deeply nested, the NeedAuthorization could also have
been forwarded via code like this — note also that I fixed the failure to
properly type the case entries in my previous message:

applySubModelOutMsg : SubModelOutMsg -> Model -> ( Model, List OutMsg )
applySubModelOutMsg subModelOutMsg model =
case subModelOutMsg of
SubModelCommand cmd ->
( model, [ Command <| Cmd.map ToSubModel cmd ] )
SubModelNeedAuthorization updateGen ->
( model, [ NeedAuthorization (updateGen >> updateSubModel) ] )


Mark


On Tue, Mar 21, 2017 at 11:26 AM, Mark Hamburg 
wrote:

> Oliver asked whether our out messages approach had an equivalent of
> Cmd.map. I'll paraphrase some code to show how it works. It's definitely
> more code than the simple Cmd approach but it provides more functionality
> as well. I'm simplifying away a lot of details like the fact that the login
> submodel below would probably be stored as a `Maybe Login.Model` since once
> we've logged in we don't need it any more.
>
> update : Msg -> Model -> ( Model, List OutMsg )
> update msg model =
> case msg of
> ToLogin loginMsg ->
> updateLogin (Login.update loginMsg) model
>
> updateLogin :
> (Login.Model -> ( Login.Model, List Login.OutMsg ))
> -> (Model -> ( Model, List OutMsg ))
> updateLogin loginUpdater model =
> Update.start model.login
> |> Update.andThen loginUpdater
> |> Update.map (asLoginIn model)
> |> Update.applyOutMessages applyLoginOutMsg
>
> asLoginIn : Model -> Login.Model -> Model
> asLoginIn model newLogin =
> { model | login = newLogin }
>
> applyLoginOutMsg : Login.OutMsg -> Model -> ( Model, List OutMsg )
> applyLoginOutMsg loginOutMsg model =
> case loginOutMsg of
> Login.Command cmd ->
> ( model, [ Command <| Cmd.map ToLogin cmd ] )
> Login.DidLogin authorization ->
> didLogin authorization model
>
> didLogin : Authorization -> Model -> ( Model, List OutMsg )
> didLogin authorization model = ...
>
> The Update module provides a collection of functions for dealing with
> types with the shape ( Model, List OutMsg ). Update.map maps the model.
> Update.andThen is a monadic chaining operation. Update.applyOutMessages
> folds the out messages over the model performing a series of updates and
> accumulating a new list of out messages (generally of a different type).
>
> Applying out messages is definitely more involved than mapping commands
> and it gets repetitive to always have to handle standard cases like mapping
> commands, but the flexibility to have the submodel signal something like
> the fact that we successfully logged in is a big win and standardizing on
> doing this via out messages builds a more consistent code rhythm than
> adding lots of one off extra results to update functions.
>
> Mark
>
> P.S. If anyone has a recommendation for a better name for
> Update.applyOutMessages, I'd love to hear it. The current name feels
> excessively verbose.
>
> P.P.S. If you want your mind more deeply twisted, here is what we do when
> we want to store the auth token fairly high up but a piece of code needs it
> for constructing an HTTP request:
>
> type SubModelOutMsg
> = Command (Cmd Msg)
>  | NeedAuthorization (Authorization -> SubModel -> ( SubModel, List
> SubModelOutMsg ))
>
> applySubModelOutMsg : SubModelOutMsg -> Model -> ( Model, List OutMsg )
> applySubModelOutMsg subModelOutMsg model =
> case subModelOutMsg of
> Command cmd ->
> ( model, [ Command <| Cmd.map ToSubModel cmd ] )
> NeedAuthorization updateGen ->
> updateSubModel (updateGen model.authorization) model
>
> updateSubModel :
> (SubModel -> ( SubModel, List SubModelOutMsg ) )
> -> (Model -> ( Model, List OutMsg ))
> updateSubModel subModelUpdater model =
> Update.start model.subModel
> |> Update.andThen subModelUpdater
> |> Update.map (asSubModelIn model)
> |> Update.applyOutMessages applySubModelOutMsg
>
>
>
> On Tue, Mar 21, 2017 at 9:11 AM, 'Rupert Smith' via Elm Discuss <
> elm-discuss@googlegroups.com> wrote:
>
>> On Monday, March 20, 2017 at 11:58:38 AM UTC, Eirik Sletteberg wrote:
>>>
>>> In larger Elm apps, it makes sense to divide Updaters so you can
>>> package-by-feature.
>>> For example, a single page application could have updaters like this:
>>>
>>> - Configuration updater
>>> - Session updater
>>> - User Profile updater
>>> - User Settings updater
>>> - Content updater
>>> - Some other business specific updater
>>>
>>> The challenge is when there are dependencies between Updaters, for
>>> example the User Profile model might need data from the Session model, the
>>> Session updater might need to send messages to the User updater (Load user
>>> profile when session is updated), or the Content updater may need to check
>>> for the Session updater (get session ID to send as parameter 

Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Mark Hamburg
Oliver asked whether our out messages approach had an equivalent of Cmd.map.
I'll paraphrase some code to show how it works. It's definitely more code
than the simple Cmd approach but it provides more functionality as well.
I'm simplifying away a lot of details like the fact that the login submodel
below would probably be stored as a `Maybe Login.Model` since once we've
logged in we don't need it any more.

update : Msg -> Model -> ( Model, List OutMsg )
update msg model =
case msg of
ToLogin loginMsg ->
updateLogin (Login.update loginMsg) model

updateLogin :
(Login.Model -> ( Login.Model, List Login.OutMsg ))
-> (Model -> ( Model, List OutMsg ))
updateLogin loginUpdater model =
Update.start model.login
|> Update.andThen loginUpdater
|> Update.map (asLoginIn model)
|> Update.applyOutMessages applyLoginOutMsg

asLoginIn : Model -> Login.Model -> Model
asLoginIn model newLogin =
{ model | login = newLogin }

applyLoginOutMsg : Login.OutMsg -> Model -> ( Model, List OutMsg )
applyLoginOutMsg loginOutMsg model =
case loginOutMsg of
Login.Command cmd ->
( model, [ Command <| Cmd.map ToLogin cmd ] )
Login.DidLogin authorization ->
didLogin authorization model

didLogin : Authorization -> Model -> ( Model, List OutMsg )
didLogin authorization model = ...

The Update module provides a collection of functions for dealing with types
with the shape ( Model, List OutMsg ). Update.map maps the model.
Update.andThen is a monadic chaining operation. Update.applyOutMessages
folds the out messages over the model performing a series of updates and
accumulating a new list of out messages (generally of a different type).

Applying out messages is definitely more involved than mapping commands and
it gets repetitive to always have to handle standard cases like mapping
commands, but the flexibility to have the submodel signal something like
the fact that we successfully logged in is a big win and standardizing on
doing this via out messages builds a more consistent code rhythm than
adding lots of one off extra results to update functions.

Mark

P.S. If anyone has a recommendation for a better name for
Update.applyOutMessages, I'd love to hear it. The current name feels
excessively verbose.

P.P.S. If you want your mind more deeply twisted, here is what we do when
we want to store the auth token fairly high up but a piece of code needs it
for constructing an HTTP request:

type SubModelOutMsg
= Command (Cmd Msg)
 | NeedAuthorization (Authorization -> SubModel -> ( SubModel, List
SubModelOutMsg ))

applySubModelOutMsg : SubModelOutMsg -> Model -> ( Model, List OutMsg )
applySubModelOutMsg subModelOutMsg model =
case subModelOutMsg of
Command cmd ->
( model, [ Command <| Cmd.map ToSubModel cmd ] )
NeedAuthorization updateGen ->
updateSubModel (updateGen model.authorization) model

updateSubModel :
(SubModel -> ( SubModel, List SubModelOutMsg ) )
-> (Model -> ( Model, List OutMsg ))
updateSubModel subModelUpdater model =
Update.start model.subModel
|> Update.andThen subModelUpdater
|> Update.map (asSubModelIn model)
|> Update.applyOutMessages applySubModelOutMsg



On Tue, Mar 21, 2017 at 9:11 AM, 'Rupert Smith' via Elm Discuss <
elm-discuss@googlegroups.com> wrote:

> On Monday, March 20, 2017 at 11:58:38 AM UTC, Eirik Sletteberg wrote:
>>
>> In larger Elm apps, it makes sense to divide Updaters so you can
>> package-by-feature.
>> For example, a single page application could have updaters like this:
>>
>> - Configuration updater
>> - Session updater
>> - User Profile updater
>> - User Settings updater
>> - Content updater
>> - Some other business specific updater
>>
>> The challenge is when there are dependencies between Updaters, for
>> example the User Profile model might need data from the Session model, the
>> Session updater might need to send messages to the User updater (Load user
>> profile when session is updated), or the Content updater may need to check
>> for the Session updater (get session ID to send as parameter to the API
>> when fetching content), or some business-specific updater may need to
>> interact with both the Content updater, the User updater, and the
>> Configuration updater.
>>
>
> I would apply a technique similar to CRC Cards from OO design. Instead of
> Class-Responsibility-Collaboration, make it Module-Responsibility-
> Collaborations.
>
> You have got a fair idea of what the split of responsibilities into
> modules is (configuration, session, user profile, user setting, content,
> and so on). For each module it is worth also explicitly spelling out what
> its dependencies (Collaborations) are. Analyzed that way, you might find a
> more optimal grouping of the responsibilities into modules that gives you
> less of a dependency head-ache. Even though that grouping may no longer
> align with your first 

[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread 'Rupert Smith' via Elm Discuss
On Monday, March 20, 2017 at 11:58:38 AM UTC, Eirik Sletteberg wrote:
>
> In larger Elm apps, it makes sense to divide Updaters so you can 
> package-by-feature.
> For example, a single page application could have updaters like this:
>
> - Configuration updater
> - Session updater
> - User Profile updater
> - User Settings updater
> - Content updater
> - Some other business specific updater
>
> The challenge is when there are dependencies between Updaters, for example 
> the User Profile model might need data from the Session model, the Session 
> updater might need to send messages to the User updater (Load user profile 
> when session is updated), or the Content updater may need to check for the 
> Session updater (get session ID to send as parameter to the API when 
> fetching content), or some business-specific updater may need to interact 
> with both the Content updater, the User updater, and the Configuration 
> updater.
>

I would apply a technique similar to CRC Cards from OO design. Instead of 
Class-Responsibility-Collaboration, make it 
Module-Responsibility-Collaborations.

You have got a fair idea of what the split of responsibilities into modules 
is (configuration, session, user profile, user setting, content, and so 
on). For each module it is worth also explicitly spelling out what its 
dependencies (Collaborations) are. Analyzed that way, you might find a more 
optimal grouping of the responsibilities into modules that gives you less 
of a dependency head-ache. Even though that grouping may no longer align 
with your first pass at splitting things up into a modular design, it may 
be a way to a better design.

Occasionally I have had a module that produces 'out messages' to signal 
some condition that an update method higher up in the structure has to deal 
with, possibly even updating the state of some other module beneath it, so 
it is effectively a side-ways message. I can see that this is a bit of a 
draw-back that modular designs sometimes inevitably lead to. I am avoiding 
modularizing too early, and using Model-Responsibility-Collaboration to 
drive the split into modules in a more optimal way, or even deciding not to 
at all if makes it apparent that I can't find a good modular design.

-- 
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.


Re: [elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Mark Hamburg
The main reason to separate is when the smaller pieces have their own
conceptual integrity. That becomes something one can manage independently
and maintain more local invariants about thereby making that piece of the
code easier to reason about. But a dependency has to be managed somewhere
and generally that needs to happen wherever things come together in the
model hierarchy.

For example, let's say we have a list of chats and a current chat. We're
going to receive the list of chats from the server. The current chat is
going to be something we're going to determine locally. The protocol that
we speak with the server might be involved enough that we want to wrap this
in its own module. (For example, the server might be shipping deltas rather
than whole lists.) One of the things that can happen is that a chat could
get deleted, so an update to the chat list could cause us to have to update
the current chat. Here is how that code roughly works out. (I've got some
monadic types that make it easier to write update functions, but I'm
staying away from them in this example.)

type alias Model =
{ chatList : ChatList.Model
, currentChat : Maybe ChatID
}

type Msg
= ToChatList ChatList.Msg
| ...

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ToChatList chatListMsg ->
updateChatList (ChatList.update chatListMsg) model

updateChatList : (ChatList.Model -> ( ChatList.Model, Cmd ChatList.Msg ) )
-> Model -> ( Model, Cmd Msg )
updateChatList chatListUpdater model =
let
( newChatList, chatListCmd ) =
chatListUdpater model.chatList
newModel =
{ model | chatList = newChatList }
cmd =
Cmd.map ToChatList chatListCmd
( finalModel, finalCmd ) =
updateChatListDependencies newModel
in
( finalModel, Cmd.batch [ cmd, finalCmd ] )

updateChatListDependencies : Model -> ( Model, Cmd Msg )
updateChatListDependencies model =
let
newCurrentChat =
model.currentChat
|> Maybe.andThen (constrainToChatList (ChatList.getList
model.chatList))
in
( { model | currentChat = newCurrentChat }, Cmd.none )

constrainToChatList : List Chat -> ChatID -> Maybe ChatID
constrainToChatList chatList chatID =
if List.any (Chat.id >> (==) chatID) chatList then
Just chatID
else
Nothing

The key logic here with respect to the dependent values is in updateChatList
and its call to updateChatListDependencies. In this implementation, the
model is not responsible for directly maintaining the list of chats but it
is responsible for maintaining the constraints that depend on the list of
chats.

Mark

On Tue, Mar 21, 2017 at 6:35 AM, Eirik Sletteberg  wrote:

> That was what I was thinking, put all the application state in one model,
> and all updaters will deal with that single model, instead of each Updater
> having its own sub-model. In the end, almost all the data is dependent
> somehow.
>
> tirsdag 21. mars 2017 12.22.15 UTC+1 skrev Fedor Nezhivoi følgende:
>>
>> > for example the User Profile model might need data from the Session
>> model
>>
>> This is probably the biggest issue with how people used to do it in
>> Redux. If you read it closely then you'll see that your data is dependent.
>> By separating it between modules you do not make it in decoupled, you just
>> create more boilerplate and complexity in how it works together. This was
>> one of the reasons Redux discarded `waitFor` mechanism from Flux. If you
>> have dependent data just put it in one reducer, that's it. I guess this
>> pretty much applies here for Elm as well.
>>
> --
> 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.
>

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Eirik Sletteberg
That was what I was thinking, put all the application state in one model, 
and all updaters will deal with that single model, instead of each Updater 
having its own sub-model. In the end, almost all the data is dependent 
somehow.

tirsdag 21. mars 2017 12.22.15 UTC+1 skrev Fedor Nezhivoi følgende:
>
> > for example the User Profile model might need data from the Session model
>
> This is probably the biggest issue with how people used to do it in Redux. 
> If you read it closely then you'll see that your data is dependent. By 
> separating it between modules you do not make it in decoupled, you just 
> create more boilerplate and complexity in how it works together. This was 
> one of the reasons Redux discarded `waitFor` mechanism from Flux. If you 
> have dependent data just put it in one reducer, that's it. I guess this 
> pretty much applies here for Elm as well.
>

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Fedor Nezhivoi
> for example the User Profile model might need data from the Session model

This is probably the biggest issue with how people used to do it in Redux. 
If you read it closely then you'll see that your data is dependent. By 
separating it between modules you do not make it in decoupled, you just 
create more boilerplate and complexity in how it works together. This was 
one of the reasons Redux discarded `waitFor` mechanism from Flux. If you 
have dependent data just put it in one reducer, that's it. I guess this 
pretty much applies here for Elm as well.

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-21 Thread Eirik Sletteberg
Is it an option to make all the updaters deal with the root model and the 
root message?
And in the "main" updater, just compose the other updaters?
It could make things simpler, but hurt isolation. Also I'm not sure whether 
that would introduce circular dependencies between modules?

mandag 20. mars 2017 12.58.38 UTC+1 skrev Eirik Sletteberg følgende:
>
> In larger Elm apps, it makes sense to divide Updaters so you can 
> package-by-feature.
> For example, a single page application could have updaters like this:
>
> - Configuration updater
> - Session updater
> - User Profile updater
> - User Settings updater
> - Content updater
> - Some other business specific updater
>
> The challenge is when there are dependencies between Updaters, for example 
> the User Profile model might need data from the Session model, the Session 
> updater might need to send messages to the User updater (Load user profile 
> when session is updated), or the Content updater may need to check for the 
> Session updater (get session ID to send as parameter to the API when 
> fetching content), or some business-specific updater may need to interact 
> with both the Content updater, the User updater, and the Configuration 
> updater.
>
> In Redux, one would use combineReducers to mount each reducer under its 
> own path, and then one can trigger actions across reducers. How would you 
> solve this in Elm?
>
>

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-20 Thread Martin Norbäck Olivers
And it helps to not think about the functions "interacting" with each 
other. They don't. A function can call another function. Nothing is 
stopping you from calling the content update function or the user update 
function from another update function, but I find it helps to just factor 
out the common functionality into separate functions that can be called 
from multiple places.

And if you have an update function that needs to update several 
"sub-models", just pass all the sub-models and get the updated sub-models 
back. Or pass the main model and let it update the parts it needs to update.


> The challenge is when there are dependencies between Updaters, for example 
>> the User Profile model might need data from the Session model, the Session 
>> updater might need to send messages to the User updater (Load user profile 
>> when session is updated), or the Content updater may need to check for the 
>> Session updater (get session ID to send as parameter to the API when 
>> fetching content), or some business-specific updater may need to interact 
>> with both the Content updater, the User updater, and the Configuration 
>> updater.
>>
>> In Redux, one would use combineReducers to mount each reducer under its 
>> own path, and then one can trigger actions across reducers. How would you 
>> solve this in Elm?
>>
>
> I find it helps to think not about sending messages to somebody but 
> returning a command. If the session updater needs to load a user profile, 
> it returns a command do to that and you map that onto the user message 
> type. If the user profile needs data from the session model, you pass that 
> data to the view function.
>
> It only gets hard when you try to think of them as separate components. 
> They're not, they are just a collection of functions. 
>

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-20 Thread Martin Norbäck Olivers


> The challenge is when there are dependencies between Updaters, for example 
> the User Profile model might need data from the Session model, the Session 
> updater might need to send messages to the User updater (Load user profile 
> when session is updated), or the Content updater may need to check for the 
> Session updater (get session ID to send as parameter to the API when 
> fetching content), or some business-specific updater may need to interact 
> with both the Content updater, the User updater, and the Configuration 
> updater.
>
> In Redux, one would use combineReducers to mount each reducer under its 
> own path, and then one can trigger actions across reducers. How would you 
> solve this in Elm?
>

I find it helps to think not about sending messages to somebody but 
returning a command. If the session updater needs to load a user profile, 
it returns a command do to that and you map that onto the user message 
type. If the user profile needs data from the session model, you pass that 
data to the view function.

It only gets hard when you try to think of them as separate components. 
They're not, they are just a collection of functions. 

-- 
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.


[elm-discuss] Re: How do you handle dependencies between updaters?

2017-03-20 Thread Dmitry Utkin
I've came up with solution very similar to Oliver's :)

Top `Page`(or `Screen`) update functions are getting the `Store` which is a 
top level app model. Alternative way is to have `mapToContext` function 
that receives some `Props` and `Store` and maps those to some useful 
context(it might be useful for both view and update functions, btw).

Each top-level `Page` update fn also returns an instance of `Action` that 
helps modifying the store.

On Monday, March 20, 2017 at 1:58:38 PM UTC+2, Eirik Sletteberg wrote:
>
> In larger Elm apps, it makes sense to divide Updaters so you can 
> package-by-feature.
> For example, a single page application could have updaters like this:
>
> - Configuration updater
> - Session updater
> - User Profile updater
> - User Settings updater
> - Content updater
> - Some other business specific updater
>
> The challenge is when there are dependencies between Updaters, for example 
> the User Profile model might need data from the Session model, the Session 
> updater might need to send messages to the User updater (Load user profile 
> when session is updated), or the Content updater may need to check for the 
> Session updater (get session ID to send as parameter to the API when 
> fetching content), or some business-specific updater may need to interact 
> with both the Content updater, the User updater, and the Configuration 
> updater.
>
> In Redux, one would use combineReducers to mount each reducer under its 
> own path, and then one can trigger actions across reducers. How would you 
> solve this in Elm?
>
>

-- 
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.