Still not entirely happy with how the delegate works, but it is simple and 
easy to build a 'delegate' helper function in the library being embedded 
should this style ever become popular.

Here is my previous example along with my Helpers library (with a delegate 
method that does not link in ProjectEx, thus making it optional, if I had 
it link in ProjectEx then I could completely get rid of the whole branch 
with a single call), and the `elm-mdl` library and showing how it fits in 
(and works perfectly):

````elm

filters : Msg -> Model -> ( Msg, States Model Msg )filters msg model =
    let
        log =
            debug_log (model.programFlags.debug_log |> Maybe.withDefault False) 
"filters" ( msg, model )
    in
        case msg of
            Helpers helpersMsg ->
                ( msg
                , States.enableAll |> States.delegate (helpers_delegate Helpers 
helpersMsg)
                )

            Mdl mdlMsg ->
                ( msg
                , States.enableAll
                    |> States.delegate
                        { key = "Mdl"
                        , update = Just (\_ o -> Material.update mdlMsg o)
                        , subscriptions = Just (\o -> Material.subscriptions 
Mdl o)
                        }
                )

            MesgList_Scroll scrolled ->
                case model.loc of
                    RoomLocation rid _ ->
                        let
                            doLoad : Bool
                            doLoad =
                                (model.firstMessageReached == False)
                                    && (scrolled.pos < 16)
                                    && (model.isLoadingOlder == False)
                                    && ((Dict.size model.active_room_msgs) >= 
10)
                        in
                            if doLoad then
                                ( MesgList_LoadOlder rid, States.enableAll )
                            else
                                ( msg, States.disableAll )

                    _ ->
                        ( msg, States.disableAll )

            _ ->
                ( msg, States.enableAll )

```

So far a good bit of the code is cleaned up, I've also filtered out some 
other messages and their states so the update is only called with them when 
it is actually warranted to do so, which removes a lot of multi-site 
testing as I can now just assume that if it reaches update then it is time 
to work on it.  Cleaning up the code beautifully.

I am still very tempted to split my Msg type into two other types, a 
MsgFilter and a MsgUpdate or so...


On Tuesday, August 9, 2016 at 11:31:08 AM UTC-6, OvermindDL1 wrote:
>
> I am not happy with delegates work, still too verbose (though still less 
> code), but I am unsure about registering them 'earlier' as someone would 
> not be able to conditionally cancel loading those if they wanted.  I might 
> keep it this way, but then again making a `delegates` callback sounds 
> enticing too, full control then...
>
>
> Either way, converted my `MesgList_Scroll scrolled` scroll callback from a 
> large mess of tons of `if <> then <> else` stuff into a filter of:
> ```elm
>
>         MesgList_Scroll scrolled ->
>             case model.loc of
>                 RoomLocation rid _ ->
>                     let
>                         doLoad : Bool
>                         doLoad =
>                             (model.firstMessageReached == False)
>                                 && (scrolled.pos < 16)
>                                 && (model.isLoadingOlder == False)
>                                 && ((Dict.size model.activeRoomMsgs) >= 10)
>                     in
>                       if doLoad then
>                         ( MesgList_LoadOlder rid, States.enableAll )
>                       else
>                         ( msg, States.disableAll )
>                 _ -> ( msg, States.disableAll )
> ```
> Which was a small fraction of the original MesgList_Scroll message, which 
> if it should do something instead of testing doLoad 4 more times I instead 
> just give a message of `MesgList_LoadOlder`, which is clean and obvious in 
> what its name does, and also reduced the size of my update function by a 
> significant amount since this was originally a very large case.  The 
> `MesgList_LoadOlder` has to do no checks on whether it needs to do 
> something and instead just does it, very clean and simple now.  If the 
> check failed then it just does and calls nothing.
>
> This case is testing message translation and callback cancellation, and it 
> is working perfectly.
>
> This case could have been done as-is in Update (since it is just a message 
> conversion) by starting up a task and submitting it back as a command, but 
> that still leaves all the conditional crap in my update, which in my 
> opinion should only update the model, thus making the *huge* update 
> function more readable.  I am half-tempted to split my Msg type up into a 
> MsgFilter and MsgUpdate types to further separate concerns.
>
> Still curious what is the best API to use for TEA delegation.  I really am 
> thinking that adding either another callback or just a simple registration 
> on main is best.  Another callback would allow for conditional control to 
> turn them on and off though, but maybe it is best if they do that 
> themselves?
>
>
> On Tuesday, August 9, 2016 at 9:46:56 AM UTC-6, OvermindDL1 wrote:
>>
>> And started integrating it into one of my main apps that can benefit most 
>> from this.  So far I changed my main function from being this:
>> ```elm
>> main : Program ProgramFlags
>> main =
>>     Navigation.programWithFlags urlParser
>>         { init = init
>>         , view = view
>>         , update = update
>>         , urlUpdate = urlUpdate
>>         , subscriptions = subscriptions
>>         }
>> ```
>> To become this:
>> ```elm
>> main : Program ProgramFlags
>> main =
>>     Navigation.programWithFlags urlParser
>>         (ProgramEx.programExBuilderWithFlagsAndNavigation
>>             { init = init
>>             , filters = filters
>>             , update = update
>>             , view = view
>>             , subscriptions = subscriptions
>>             , urlUpdate = urlUpdate
>>             }
>>         )
>> ```
>> I also added an `import ProjectEx` and `import ProjectEx as States 
>> exposing (States)` at the top too.
>>
>> And I added a filter callback function of:
>> ```elm
>> filters : Msg -> Model -> ( Msg, States )
>> filters msg model =
>>     case msg of
>>         _ ->
>>             ( msg, States.default )
>> ```
>> And it works (by doing nothing different yet)!
>>
>> I decided to add the model as a read-only into the filter as it ended up 
>> being quite useful in prior tests.  Now to start converting some of my ton 
>> of boilerplate into this and see if and by how much if so it reduces 
>> boilerplate.
>>
>> This version is not uploaded yet, want to make sure no real bugs or 
>> anything first, and I figure a real project is a good way to test.
>>
>

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

Reply via email to