DEV Community

Richard Wood for ElmUpdate

Posted on

Implementing Elm Toasts

When you want to send briefly displayed messages to the user of your web application, Toasts are a cool way to do it. You know those little boxes that show up on the side and disappear after a while.

Without anything in place so far to display errors or confirm activity I went hunting for what Elm had to offer.

There weren't a lot of offerings, but Toasty (http://package.elm-lang.org/packages/pablen/toasty/1.0.4/Toasty) looked like it had some good customisation capability and the demo certainly looked the part.

alt text

In my ideal world I'd install the package, edit a config file and start calling the module. Oops, that sounds like Javascript...

In this case there was stuff to add to the Model, initial model, a type alias, an update branch, and view stuff. I don't know if this is the price of type safety, or how possible it is to make Elm modules more independent. I'm just grateful people are writing these libraries at all.

AS STEP 1 - I recommend just following the instructions on that part of it.

At about this point and after playing around with Toasty.config things weren't working for me in that I was getting text showing on the screen that disappeared - good - but no box around it - bad.

Usually I skim read things and assume a 'work-out-of-the-box' mentality. Then when I hit problems I go back. In this case I re-read the opening bit which mentioned Toasty.Defaults. This gave me a starter Toast definition, which was handy but I wasn't otherwise much the wiser.

So time to read or at least look at the source code. Whamo there's an example App.elm in there that appears to be the code for the demo. I also found there Defaults.css and Toasty.Defaults, which you can customise. I needed to reposition my Toasts and change the widths for example.

AS STEP 2 - Bring Defaults.css and Toasty.Defaults into the app and customize to your needs. Then make sure all your references to myConfig are to Toasty.Defaults.config

This provided the missing pieces I needed to get it up and running.

Now I only had one issue remaining. I really wanted a minimum calling api. The site was suggesting putting this on the end of update functions:

|> Toasty.addToast myConfig ToastyMsg (MyToast "Entity successfully created!")
Enter fullscreen mode Exit fullscreen mode

I liked the idea of feeding from update functions but there is no way I'm going to litter the code with lots of those.

The App.elm example had another version of addToast that simplified things to:

|> addToast (Toasty.Defaults.Success "Allright!" "Thing successfully updated")
Enter fullscreen mode Exit fullscreen mode

I really just wanted to cover 90% of usage with something like:

|> doToast Toasty.Defaults.Success "Success" "You did it" 
Enter fullscreen mode Exit fullscreen mode

This can be achieved by adding a helper function that assumes the config file and Update message names:

doToast toast title message = 
    Toasty.addToast 
        Toasty.Defaults.config 
        ToastyMsg (toast title message)
Enter fullscreen mode Exit fullscreen mode

or what I really wanted was:

|> doToast "Success" "You did it!" 
Enter fullscreen mode Exit fullscreen mode

So (purists please avert your eyes):

doToast : String -> String -> ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
doToast title message =

    let
        toast = case title of 
            "Success" -> 
                Toasty.Defaults.Success title message
            "Error" -> 
                Toasty.Defaults.Error title message
            "Warning" -> 
                Toasty.Defaults.Warning title message
            _ -> 
                Toasty.Defaults.Success title message
    in

    Toasty.addToast 
        Toasty.Defaults.config 
        ToastyMsg toast
Enter fullscreen mode Exit fullscreen mode

AS STEP 3. Make your own helper(s) that keep it simple and flexible for you. For example you may want to specify the length of time each toast displays for. That's just one of the config options you have with Toasty that I haven't covered here.

In summary: A very useful and flexible module that in the scheme of things did not take long to get up and running.

Top comments (3)

Collapse
 
pablen profile image
Pablo Enrici

Hi Richard! I'm glad you liked Toasty and grateful you took the time to share here your experience using it. Certainly explaining things on a README file is not one of my strengths 😕but at least the example file is a bit more clear 😅.

I wrote that package a couple of months ago and coming from a JavaScript background I struggled a lot trying to come up with something like a "plugin" that plays nicely with The Elm Architecture. The first thing I instinctively tried to achieve was encapsulating the module somehow so that it wouldn't pollute the application code, but then I figured it would be better to follow TEA more closely and provide the different separate pieces and let the users integrate them in their own architecture. I'm still not completely sure what the best answer for this problem is, but I guess that the "plug&play" versatility that JS libraries commonly have is simply not posible in Elm, an maybe for the best.

Thanks again for writing this!

Collapse
 
g4bb3r profile image
Gabriel Torrecillas Sartori

The last function doToast is unsafe due to pattern matching on string!
Why not providing 3 functions? doToastSuccess, doToastError and doToastWarning?

Collapse
 
rwoodnz profile image
Richard Wood • Edited

Thank you. That is a good idea! Have done exactly that.