So far, we’ve had the idea to digitalize our white boards, we’ve shaped and modeled our domain using domain-driven design, and then we turned this domain into a real-time API. One last important thing missing here is a user interface that lets us attach post-its to our digital whiteboards, so let’s talk about how we’ve built the client that actually talks to our wolkenkit backend.
Just like in the previous step, let’s first spend some time talking about what we actually want to build. We want to have a screen where people can mount new boards because we don’t want to limit ourselves to just brainstorming about Monday meetings. Each board has a unique link and can easily be shared with other people by sending out a link.
Once you click on a board, you’re taken to the board screen showing all of the post-its attached to it. What we really like about the post-it metaphor is the fact that post-its have limited space, so you actually do need some focus when noting down thoughts on them. That’s something we wanted to preserve in the digital version. The post-its should autosize themselves to a certain height, but they should definitely not invite the user to write large amounts of texts – only brief, quick thoughts. But we also wanted to extend the digital version: you can add links to them, and you can simply drag images from your desktop and drop them on a board. We truly believe that work should be playful, so we thought about adding a very subtle physical behavior to the post-its while dragging them around.
What we get back from this function call is an application object, which we’ve called api. Through some nice magic inside of this connect function, the app contains all the objects we defined in the readModel and writeModel folders of our wolkenkit application. Now we can start using them to reach out to the backend.
So the first thing we’d like to do is to mount a new board whenever somebody hits
In order to do so, we trigger some handler code whenever the form is submitted by the user. Our application is now able to use the api object to send the mount command to a new board.
The client SDK contains some helpers to deal with the asynchronous nature of commands and events. For example, the await function lets us wait until a specific event occurs in response to a sent command. An additional timeout handler can be used to trigger logic if the event doesn’t occur in a given amount of time. There are a lot more details to discover, and you can read about them in the wolkenkit documentation on sending commands.
Now that we’ve changed the application’s state by sending a command, let’s look at an example of how to read this state.
One example for reading application state is fetching the list of all the posts for the active board. Obviously this is something we would read more than once since we would like to stay up-to-date while people are collaborating. Luckily we don’t have to worry about this – wolkenkit lets us read and observe read models. Whenever something changes inside a list read model on the server, our app will be informed about that change. We simply have to re-render our user interface.
The api object therefore contains a context for lists. We can use it to reach out to the list of posts and call the readAndObserve function. Again we get some async helper methods (started, updated and failed) to subscribe to the lifecycle of a list. The most important thing to note here is that inside the updated callback, we get an array of posts that we can use to re-render the board. There’s a lot more information to discover about reading lists over at docs.wolkenkit.io. But for now let’s just see how it feels inside our app…
While we’re issuing commands, e.g., we’re attaching a post to board, we’re moving it around, our list of posts gets updated for us. These are two of the most important parts of our client. We’ve come a long way and built a simplistic single-page application that talks to our backend running in the cloud. In the next part of this series, we’ll sum things up, see what we’ve learned so far, and release the source code.