Josh, The code snippet you wrote is just the standard architecture. This is what I would expect..
But, if I'm understanding your previous messages correctly, it sounds like you're suggesting that nested components should "message" (such as with OutMsg in the brian hicks article you recommended <https://www.brianthicks.com/post/2016/06/23/candy-and-allowances-parent-child-communication-in-elm/>) to their direct parent when requesting data. If that's correct, I think you're going to run into some problems. I'm assuming your child component might message something like this: module Child exposing(..) -- model... type Msg = ResourceRequested | ResourceLoading | ResourceFailed type OutMsg = *GiveMeResourceById String* update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg ) update msg model = case msg of ResourceRequested -> ( model, Cmd.none, Just *GiveMeResourceById "2353253"* ) Great, *GiveMeResourceById* has been passed upwards to the parent. We know the Parent will need to pass a Parent.OutMsg upwards to the grandparent, but unfortunately, we can't simply wrap the Child.OutMsg in a Parent.OutMsg as we normally would since we'd lose all context of the child's request - The Grandparent would receive a generic Parent.OutMsg and wonder "what do I do with this?". module Parent exposing (..) import Child type OutMsg = *ChildOutMsg Child.OutMsg* -- wait! this won't work update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg ) Instead, rather than wrapping the child's OutMsg, the parent would likely return a brand new local OutMsg that communicates the child's original intent, and value: module Parent exposing (..) import Child type Msg = ChildMsg Child.Msg type OutMsg = GiveChildResourceById String update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg ) update msg model = case msg of ChildMsg submsg -> let (childModel, childCmd, childOutMsg) = Child.update submsg model.childModel in ( { model | childModel = childModel }, Cmd.map ChildMsg loginCmd, convertChildOutMsg childOutMsg ) convertChildOutMsg : Maybe Child.OutMsg -> Maybe Parent.OutMsg convertChildOutMsg msg = case msg of Just Child.GiveMeResourceById id -> Just GiveChildResourceById id Nothing -> Nothing This process will be repeated between child and parent until we reach the root. Great... so the root has now processed the request and is ready to return data. How does it do that? The original suggestion of passing values down using the TEA no longer works, since the OutMsgs were not wrapped on the way up... there is nothing to unwrap on the way down. case msg of ... Apple msg -> { model | apple = Apple.update(msg) } -- handwavy, you want to catch `Cmd` as well Api msg -> { model | api = Api.update(msg) } -- ditto, deal with Cmd like in Keyboard.extra The components msgs must be generated and converted from parent context to child context each downward step. If you expand this to multiple child components each making multiple api requests, you're going to quickly have OutMsg explosion - Each child's OutMsg involved in api request will be duplicated in its parent, and its parent.. all the way up to the root. Here is a hicks article that also briefly touches on this point.. https://www.brianthicks.com/post/2016/07/05/duplicate-message-or-update-contexts-in-elm-components/ Anyways, this is getting somewhat away from the issue that I'm having with Authentication. I think I'll open a new thread with a more direct question. Thanks again for the suggestions Josh. On Tuesday, July 5, 2016 at 8:46:13 PM UTC-4, Josh Adams wrote: > > If it then needs to proxy requests through its direct parent - the >> AdminComponent - the AdminComponent will contain message like: >> >> type Msg >> = LoadAppleComponentApples >> | AppleComponentApplesLoading >> | AppleComponentApplesFailure Error >> | AppleComponentApplesSuccess Data >> ... etc etc for each Component type >> >> Is this still on par with what you're suggesting? >> > > Aha, no. See the README for Keyboard.Extra - > http://package.elm-lang.org/packages/ohanhi/keyboard-extra/1.0.1 > > A typical TEA would see something like a single tag for a given component > in the parent, and routing messages through to it. So in general I would > expect to see something like: > > case msg of > ... > Apple msg -> > { model | apple = Apple.update(msg) } -- handwavy, you want to catch > `Cmd` as well > Api msg -> > { model | api = Api.update(msg) } -- ditto, deal with Cmd like in > Keyboard.extra > > Then I could see the API supporting `LoadApples` or some such, and getting > that message up to the Root by saying `AskForApples`. The root would proxy > to the API, and it would use the messages it knows about re: telling > AppleComponent about new data - presumably it got its data from somewhere > upstream. > > I might be in vehement agreement with you here - I think you're worried > about incidental complexity and I'm worried about coupling. I *really* > want someone else to pipe in because I fear I might be sending you on a > wild goose chase, but I've spent a lot of time thinking about these things > without yet having built something of decent size in Elm (lots and lots and > lots of toys though!). In general, though, the idea of a component knowing > about the backend API sends chills up my spine. > > -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
