Skip to content

Instantly share code, notes, and snippets.

@JoelQ
Created January 10, 2020 20:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoelQ/85c0d59e7ad3d3efb7ba7c7d0387a3d8 to your computer and use it in GitHub Desktop.
Save JoelQ/85c0d59e7ad3d3efb7ba7c7d0387a3d8 to your computer and use it in GitHub Desktop.

Domain-Specific Views in Elm

Ironically, in our front-end code the views often get the least love. In non-trivial apps they quickly become a nested tangle of tags, classes, and conditional logic. Extracting functions can only go so far. There is a better way.

Join me on a quest to turn our views from HTML soup into a domain-specific description of our UI elements. We'll explore several strategies for achieving this including both the top-down, bottom-up, and layered approaches to structuring functions. You'll leave empowered to write view code that's both flexible and readable.

Details

The view is an often neglected part of our code. It tends to be made up of large chunks of nested HTML functions, riddled with duplication, and punctuated by conditionals. Many try to combine state and UI by trying to create "components". I've found a simpler approach yields great results.

We can use regular functions to add a thin level of abstraction above the HTML helpers. We end up writing something that almost looks like a "domain specific language" describing the various visual elements we use on our page. For example a survey view might be described in terms of "section", "multiple choice question", and "free-form question". Whether these are implemented as nested divs or as tables is irrelevant most of the time we're working in that code.

This leads to tremendous readability boosts by focusing on the higher-level concepts that actually matter in the view. In addition, building views like this decouples them from the HTML structure and CSS classes used to implement them, allowing them to be easily modified and shared.

I'll be looking at several examples including more specialized views like surveys and shared app UI pieces like tables and titled sections.

Some concepts I'll be exploring are:

  • Building from the top-down (passing all the data into the top-level function)
  • Building from the bottom-up (passing constructed children to the parent function, similar to the Html library)
  • Handling messages and events
  • Decoupling content from decisions
  • How to deal with special cases
  • Avoiding the traps of over-abstracting and over-configuring
  • The "layered" architecture of building-lower level functions that take many arguments and then defining higher-level functions with fewer args for the 80% case in terms of the lower-level ones.

Pitch

I've consulted on multiple Elm projects as well as been active helping people online. In most non-trivial apps, the view code tends to be a low-level tangled mess once the app reaches a certain size. I've had great success avoiding raw HTML functions in my views in favor of higher-level semantic helpers. The reaction from clients and colleagues has been overwhelmingly positive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment