Code Monkey home page Code Monkey logo

Comments (9)

seanhess avatar seanhess commented on May 16, 2024 1

@evancz The new section is soooo good. This week I'm training a team on Elm and have a huge section trying to convince people to reach for functions instead of TEA modules, and I'm glad to see you recommending the same thing.

from elm-architecture-tutorial.

seanhess avatar seanhess commented on May 16, 2024

@sindikat I can answer the question about displaying data. If you follow the State vs Props idea in that thread, you look up the correct options to pass in your view function:

    type alias ChildProps = { options : List String }
    type alias ChildState = { selected : Maybe Int, inputField : String }
    type alias ParentModel = { players : List String, actions : Dict String (List String), currentPlayer : String, childState : ChildState }

    parentView address model = 
       let options = Maybe.withDefault [] (Dict.get model.currentPlayer model.actions) in
       div [] [ Child.view { options = options } model.childState ]

However, I came here to ask about passing data back to parents. I'm running into it over and over again, any time I want to create generic components. Especially when I need to manipulate my own state, and also report something back to the parent, as the result of one user action.

Should we make a separate issue for that? I really need feedback from someone more experienced on this.

from elm-architecture-tutorial.

evancz avatar evancz commented on May 16, 2024

@seanhess, you can use a tuple for that.

update : Action -> Model -> (Model, MessageForParent)

If you need effects too, you can have them the same way.

update : Action -> Model -> (Model, MessageForParent, Effects Action)

It's the same idea whether we are passing up an effect or any other value.

I don't know if this is "the ideal way" but this definitely should not block folks.

from elm-architecture-tutorial.

evancz avatar evancz commented on May 16, 2024

Maybe I took the extra generic types out of the tutorial when I added examples 5 through 8. The very generic version of things is:

update : UpdateContext -> Action -> Model -> (Model, whatever)

view : ViewContext -> Address Action -> Model -> Html

You don't have to follow this like a law, it's just for illustration. With update you can demand that the caller gives you some "context" that you do not own. So the parent can give any relevant info. Same with the view, you can demand info from the parent.

Then you can give info back to the parent in the return type of update. Whatever it is you want them to know about, just pass it out to them.

from elm-architecture-tutorial.

seanhess avatar seanhess commented on May 16, 2024

@evancz thanks so much for chiming in! I had started doing it this way but I wasn't sure if I was way off in the weeds or not. This is very useful, thank you.

from elm-architecture-tutorial.

 avatar commented on May 16, 2024

This makes more sense. The 'context' example was very confusing to me in the tutorial.

In my beginner brain I really want to be able to respond to a child's actions from inside a parent without having to change the child implementation, if that's possible...

I imagine something like this, but I can't get it past the compiler. When you run into a particular child action, do some special behavior, otherwise "fallthrough" and let the child update itself just as it normally would:

-- parent
update: Action -> Model -> Model
update act model =
    case act of
        ChildAction msg ->
            case msg of 
                ChildAction.Something someChildVal ->
                    { model | parentValue = manipulate someChildVal }
                ChildAction.AnotherThing ->
                    ...
                _ ->
                    { model | child = Child.update msg model.child }

        ParentAction ->
            ...

Not really sure why this doesn't work, but I expect its because my signature would have to be something more like Action -> NestedAction -> Model -> Model.

It has been suggested to me to "recurse" my way through this, but this just feels like a foot gun:

-- child
decode: Action -> Maybe String
decode act =
    case act of 
        ChildAction msg ->
            Just msg
        _ ->
            Nothing


-- parent
update act model = 
    case act of
        ChildAction  msg ->
            let
                model' = { model | child = Child.update msg model.child }
            in
                case Child.decode msg of
                    Nothing ->
                        model'
                    Just str ->
                        update (HandleChildAction str) model'
        HandleChildAction str ->
            { model | parentValue = manipulate str }

Is there a better way? My biggest focus is on not having to change a reusable component's interface or return parameters if at all possible. It just feels like tight coupling to have to do (Model, MessageForParent), because suddenly now you should probably modify your component's model too to include { addrOfParent: Maybe Address }, which means you have to handle the Maybe case when you do or do not want to notify the parent.

from elm-architecture-tutorial.

pinx avatar pinx commented on May 16, 2024

This has been bugging me as well. Hope it makes it into the tutorial one day.

from elm-architecture-tutorial.

evancz avatar evancz commented on May 16, 2024

Beginning of written advice in the right direction http://guide.elm-lang.org/reuse/

from elm-architecture-tutorial.

evancz avatar evancz commented on May 16, 2024

Thanks! I was worried it was a bit too short, but I'm glad folks feel it's pointing them in the right direction :D

from elm-architecture-tutorial.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.