This is part 3 of the series IHP with Elm
We have set up a single widget and most of our logic lives in a single Main.elm
file.
Since we are planning on creating an application supporting multiple isolated widgets, we might as well split this application into smaller more maintainable sub-modules with their own seperate model, view and update functions.
A simplified version of Richard Feldmans's RealWord Example app is a great architecture for this use-case.
Continue from part two
If you haven't done part 2 of this series, do so first.
If you don't want to, you could clone the project source and checkout to this tag to follow along:
Separating the BookWidget module
Inside the elm
folder, let's create a sub-folder named Widget
, and a module inside named Book.elm
Let us extract all the relevant logic into elm/Widget/Book.elm
.
What's nice about this is that we now can maintain this entire widget inside this isolated module.
Now we need to rewrite Main.elm
into a central hub that can support many different Elm widgets.
Add a new widget
Let's start the process of adding a new widget. As you might have guessed, it starts with Haskell.
The first thing we need to do is to add it to the Widget type in /Application/Helper/View.hs
:
We can also add a new widget entrypoint named bookSearchWidget
.
This one won't use any initial data from IHP. Therefore, we won't need to pass in any data other than the Widget
type's representation on the BookSearchWiget
.
Make sure the module exposes the bookSearchWidget
at the module definition.
Add widget to view
To demonstrate that we can insert many Elm views into one page, let's also add the bookSearchWidget
into /Web/View/Books/Show.hs
.
Break the app
We should now generate the types for the new Elm widgets defined in Haskell.
Imagine someone saying this for a JavaScript tutorial: Let's break the app to make it better.
Close the server (ctrl+c) and start it again with the start script that will generate the new Elm types before starting the server.
Main.elm
should now be complaining. Good! Let's first make the separate BookSearch
module.
Make the initial BookSearch widget
First create a new file for the new Widget.
Then create a simple module to start with.
Add the new widget to Main.elm
To finally get rid of the Elm errors, let's fix Main.elm
step-by-step.
First, let's import the new widget module into Main.
The Model
and Msg
types in Main needs to be have a variant for BookSearch.
The Main update
function also needs to deal with the sub-module. This looks complicated, but it's worth it 😄 Next time you add something, just follow the pattern.
Keep on just adding to the pattern with subscriptions
and view
.
The last thing the compiler should complain about is widgetFlagToModel
and widgetFlagToCmd
. These ones decides the initial state and commands (actions) upon startup of the widget.
Going into any book, you should now see a very dumb widget below that is just a title:
Next up
We will finalize this simple book app by making the new BookSearch
widget more advanced with basic search functionality.
By doing this, we will walk through the final part of doing IHP interop Elm: JSON HTTP requests with IHP through Elm. And we'll finally get to update some Elm state 😊
- Read part 4: Make http requests from Elm to IHP