Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger update call from within update

Tags:

elm

I've got a situation where I've got two ways to play a musical note within an Elm app, and I keep track of which notes are currently playing. The current code is here:

  update : Msg -> Model -> ( Model, Cmd Msg )
  update msg model =
      case msg of
          PlayNote note ->
              let
                updatedCurrentPlaying =
                  note :: model.currentPlaying
              in
                ( { model | currentPlaying = updatedCurrentPlaying }, Cmd.none )


          KeyDown keyCode ->
            let
                note =
                  List.filter (\x -> x.keyCode == keyCode) model.notes
                  |> List.head

                updatedCurrentPlaying =
                  case note of
                    Nothing ->
                      model.currentPlaying
                    Just a ->
                      a :: model.currentPlaying
            in
              ( { model | currentPlaying = updatedCurrentPlaying }, Cmd.none )

What I want to know is if there is anyway to DRY this up a bit, and cause the KeyDown case to trigger a PlayerNote note Msg rather than duplication the functionality. I've tried replacing Cmd.none with something involving Task and calling update directly but it doesn't seem to work.

Am I going about this the entirely wrong way? Is this not something that's really allowed in elm?

like image 487
redroot Avatar asked Feb 06 '18 17:02

redroot


1 Answers

Recall that update is just a function and can be called like any other function. You can just call it recursively passing the PlayNote Msg:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        PlayNote note ->
            let
                updatedCurrentPlaying =
                    note :: model.currentPlaying
            in
            ( { model | currentPlaying = updatedCurrentPlaying }, Cmd.none )


        KeyDown keyCode ->
            let
                note =
                    List.filter (\x -> x.keyCode == keyCode) model.notes
                    |> List.head

            in
            case note of
                Nothing ->
                    ( model, Cmd.none )

                Just a ->
                    update (PlayNote a) model
like image 156
Chad Gilbert Avatar answered Nov 05 '22 05:11

Chad Gilbert