[elm-discuss] Re: Communicating from parent to child and child to parent

2016-07-01 Thread Wouter In t Velt
Hi Rex,

I hope I interpret your setup correctly, but it looks like the flow is more 
or less:


   - user clicks a button inside child
   - this triggers child's update function
   - child's update function stores updates child model (with a message 
   Click)
   - the parent can then access the new function by accessing the child's 
   model
   
What I do not understand is: you mention an UpdateButton message that the 
parent responds to,

But what triggers this message?

Typically, the parent does not know or care about child model contents or 
child model updates. The parent receives child messages, but parent does 
not read child messages. Parent simply passes the messages on to the 
child's update function, and stores the updated child model.

 

This separation guarantees that you can modify code in your child component 
(e.g. change the child model, add new message types etc), and any parent 
will continue to work properly. No need to check or change code in any 
other component that imports the child.

If any parent 'looks inside' the model or the messages of the child, then 
this guarantee breaks down.

 

The discussion here (or at least my interest in this) is:

How do I communicate a message from a child to parent, while at the same 
time maintaining the integrity of the child's model (so no peeking by 
parents into child model)?

 

-- 
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: Communicating from parent to child and child to parent

2016-07-01 Thread Wouter In t Velt
I hope I interpret your setup correctly, but it looks like the flow is more 
or less:

   - user clicks a button inside child
   - this triggers child's update function
   - child's update function stores updates child model (with a message 
   Click)
   - the parent can then access the new function by accessing the child's 
   model

What I do not understand is: you mention an UpdateButton message that the 
parent responds to,
But what triggers this message?
Typically, the parent does not know or care about child model contents or 
child model updates. The parent receives child messages, but parent does 
not read child messages. Parent simply passes the messages on the child's 
update function, and stores the updated child model.

This separation guarantees that you can modify code in your child component 
(e.g. change the child model, add new message types etc), and any parent 
will continue to work properly. No need to check or change code in any 
other component that imports the child.
If any parent 'looks inside' the model or the messages of the child, then 
this guarantee breaks down.

The discussion here (or at least my interest in this) is:
How do I communicate a message from a child to parent, while at the same 
time maintaining the integrity of the child's model (so no peeking by 
parents into child model)?

-- 
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: Communicating from parent to child and child to parent

2016-06-29 Thread Rex van der Spuy
Hi Everyone!

I'm confused about why this needs to be so complex?

For example, let's say you have a button child that needs to to communicate 
its state to its parent.
You could create a `currentMsg` property on the child button model like 
this:

type alias ButtonModel = { currentMsg : Msg }

Then when the child button is clicked, capture the current message on that 
same child model:

update message childModel =
  case message of
   Click ->
{ childModel 
| currentMsg = message
}

The parent has a reference to that child button in its model:

type alias ParentModel = { button : Button.ButtonModel }

Then in the parent's `update` function, there might be an `UpdateButton` 
message that updates the child button's state and does something based on 
the value of `button.currentMsg` 

 if parentModel.button.currentMsg == Click then -- do something useful

This is how I've handled all my child-to-parent communication in the last 
few apps I've built.

Can someone tell me if this is a bad idea or if there's a crucial part of 
the problem I'm not understanding?
Is there a use case where this would not work?


-- 
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: Communicating from parent to child and child to parent

2016-06-29 Thread Mark Hamburg
In my app, I changed the standard update signature from:

msg -> model -> ( model, Cmd msg )

to:

msg -> model -> ( Maybe model, List msg, List notification )

Here was the reasoning for each of the changes:

1. Returning Maybe model: Laziness in view generation depends on not needlessly 
changing the data being passed to a view function. Originally, I was handling 
this by checking the results of sub-model updates for equality before updating 
the containing model. That approach, however, can run afoul of the fact that 
Elm doesn't like to compare functions for equality, so if your sub-model 
happens to contains a function, the equality comparison can result in 
JavaScript assertions. (Or at least it could in 0.16.) [*] So, instead, it 
seemed better to let update functions signal that they didn't change the model 
and maybe provided a good way to do that.

2. Lists of messages rather than a single command: This made the no command 
case easier to write — [] — and the batch function just wraps the list anyway.

3. Lists of notifications: This third parameter provides a way to pass 
information back up the hierarchy. For example, I have a notification that adds 
an error to a globally managed error list. Lower-level update functions can 
just observe that something went wrong, not update the model, and report the 
error up to the level where they are being collected. But this mechanism also 
allows the login logic to return a "LoggedIn userid" notification to the main 
app state manager.

I've contemplated merging the commands and the notifications to get things down 
from three to two but they do behave rather differently. Commands get annotated 
with additional routing as they move up the hierarchy and are expected to flow 
out to the app logic to interact with the outside world. In contrast, 
notifications are destined for upper levels within the model update process and 
can absorbed, transformed, or passed on as appropriate. The passed on part is 
important. Where a command will get mapped so that it's result comes back to 
the sender, a notification isn't expected to come back anywhere and hence 
doesn't need mapping unless we have to change notification types.

This approach has only been in place for a while so I'm not ready to give a 
definitive report, but it has seemed to clean up a lot of ad hoc logic.

Mark

[*] I've thought about whether Elm should fallback to essentially 
creation-defined equality — i.e.., values are equal if and only if they are the 
same JavaScript object — or offer an operator providing this test, but doing so 
would mean that various compiler optimizations could change the meaning of 
programs, so it's probably not a good idea.

-- 
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: Communicating from parent to child and child to parent

2016-06-28 Thread Mark Hamburg
On Jun 28, 2016, at 6:12 AM, Wouter In t Velt  wrote:
> 
> My specific use case: I have a list of children with a number of internal 
> messages (e.g. updates on each child). One of the functions I need to 
> implement is 'RemoveMeFromList', which is a button on each child. This 
> message type can only be handled by the parent, through removing child from 
> list and no longer rendering it in view.

This is a place where presentation (view) hierarchy and data (model) hierarchy 
mix uncomfortably. Removal from the list of children has little to do with the 
child unless there are other updates that accompany the removal that only the 
child understands. It is purely an update to the parent. This is different from 
the child needing a way to express "I've run out of money". That is based on an 
update to information local to the child. What muddles this up is that the 
remove button is often presented as part of the presentation of the child and, 
in The Elm Architecture, we are trained to think of the presentation as being 
built by a view function from model to HTML and hence if the presentation 
contains a removal button then remove must be a message destined for the model.

The Elm 0.16 architecture tutorial handled this by providing a separate address 
to which the remove message could be delivered.

The Elm 0.17 documentation at present is silent on the subject. There have been 
proposals for how to deal with this in an Elm 0.16 style but they haven't been 
officially endorsed and result in view functions with a return type of Html 
parentMsg as opposed to Html ChildMsg which is a little ugly. There are also 
suggestions to use extra return values from the update function (as the essays 
linked to in this thread do) but those result in the child update function 
containing entries that basically just serve to route the remove message up to 
the parent thereby contaminating the update function with a complexity that 
previously only affected the view function.

I've still been on Elm 0.16 because I've been waiting for key support, but I've 
been looking at 0.17 and one thing that does have me worried is that in getting 
rid of addresses may have increased coupling between the view hierarchy — 
driven by UX design concerns — and the model hierarchy which should be driven 
by data consistency concerns. While the default handling in the past for 
addresses led to a tight correspondence between the hierarchies, one could 
always work around it by providing an address along with a model (or as part of 
a model) wherever appropriate and it didn't feel too unnatural. One could 
probably do something similar by using routing functions(*) in much the same 
way as addresses in 0.16 but they feel like a fight against the intended use 
pattern.

But all of those judgments are suspended pending more complete documentation 
for these cases for 0.17.

Mark

(*) view : (msg -> rootMsg) -> model -> Html rootMsg

This could just use the standard Elm 0.17 routing instead (or in its 
implementation) but it stresses that the route isn't driven by the presentation 
but is rather information describing how to get messages to the relevant 
portion of the model.

To make it work well with lazy HTML, it really needs to be based on embedding 
the route into the model and only computing it at initialization time for that 
piece of the model.

-- 
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: Communicating from parent to child and child to parent

2016-06-28 Thread Brian Hicks
The kind of message you describe in your example is definitely something 
that should be owned by the parent. It has more to do with the parent 
component than the child. It could definitely be moved to the child with a 
name change though. "Retire" or something like that.

The motivation of having the OutMsg on the child in general is to allow 
reuse of the child components. Take a "card" component, for example: you 
might have multiple components with varying content, but all producing the 
same message. You might also be using the component in multiple places. In 
that case, you would have to define the OutMsg on the child anyway, since 
otherwise you'd have a conflict between returning ParentA.InMsg and 
ParentB.InMsg.

There are multiple ways to structure this, but my experience tells me that 
the child should own all messages it consumes and produces.

On Tuesday, June 28, 2016 at 5:12:23 AM UTC-5, Wouter In t Velt wrote:
>
> Thanks for sharing. The additional OutMsg from the update function was a 
> real eye-opener for me.
> I have no experience (yet) in scaling this.
>
> One thing I find somewhat odd in your (second) example is that you define 
> the OutMsg type in the Child:
> Wouldn't it be more logical to always define/ manage Message types in the 
> component that actually handles these Messages and has an update function 
> for this?
>
> In your example, the parent is the Owner of the OutMsg: the parent has 
> separate update function(s) for dealing with each of the OutMsg types.
> To prevent circular import references (parent importing child, and child 
> importing parent), one would need to separate out parent and child into 
> separate files (as in the - not 0.17 yet - example of the Players in the 
> Elm docs).
>
> That way, any child component of parent can import the OutMsg type (maybe 
> ParentPublicMsg would be a more appropriate name). Then the parent exposes 
> this type for any child that wishes to send out such a message. When you 
> then expand OutMsg with, say AskForMoreAllowance, you add it to the 
> parent-owned type + to the parent's update function. Children can be 
> updated to respond to the new OutMsg type, but better still: any child 
> component which is not updated will continue to work.
>
> My specific use case: I have a list of children with a number of internal 
> messages (e.g. updates on each child). One of the functions I need to 
> implement is 'RemoveMeFromList', which is a button on each child. This 
> message type can only be handled by the parent, through removing child from 
> list and no longer rendering it in view.
>

-- 
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: Communicating from parent to child and child to parent

2016-06-28 Thread Wouter In t Velt
Thanks for sharing. The additional OutMsg from the update function was a 
real eye-opener for me.
I have no experience (yet) in scaling this.

One thing I find somewhat odd in your (second) example is that you define 
the OutMsg type in the Child:
Wouldn't it be more logical to always define/ manage Message types in the 
component that actually handles these Messages and has an update function 
for this?

In your example, the parent is the Owner of the OutMsg: the parent has 
separate update function(s) for dealing with each of the OutMsg types.
To prevent circular import references (parent importing child, and child 
importing parent), one would need to separate out parent and child into 
separate files (as in the - not 0.17 yet - example of the Players in the 
Elm docs).

That way, any child component of parent can import the OutMsg type (maybe 
ParentPublicMsg would be a more appropriate name). Then the parent exposes 
this type for any child that wishes to send out such a message. When you 
then expand OutMsg with, say AskForMoreAllowance, you add it to the 
parent-owned type + to the parent's update function. Children can be 
updated to respond to the new OutMsg type, but better still: any child 
component which is not updated will continue to work.

My specific use case: I have a list of children with a number of internal 
messages (e.g. updates on each child). One of the functions I need to 
implement is 'RemoveMeFromList', which is a button on each child. This 
message type can only be handled by the parent, through removing child from 
list and no longer rendering it in view.

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