Using Modapp
How to write client applications using ModappWe will base this guide on Book Collection example, which shows an editable list of books, with their titles and authors. To try out the example, visit the link and follow the instructions.
Before we go into the code on how to use ResClient together with Modapp components, we need to have a look at what Modapp is.
What is Modapp?
Modapp1 is a framework developed by Samuel Jirénius, creator of Resgate, and is described as:
A thin framework for building modular web applications.
In itself, it contains no code for component rendering. Instead it defines a set of simple interfaces which can be used together to build powerful applications.
Note
Modapp components generally renders faster, with less code, and smaller footprint, than virtual DOM based renderers such as React, Angular, and Vue.js.
Modapp defines the following interfaces relevant to ResClient.
Component interface
A Modapp component2 is a self contained UI component that can render itself on the DOM. It must have the following methods:
render(el)
- Renders the component by appending its elements to the provided parent elementunrender()
- Unrenders the component and removes its elements to from the parent element
Model interface
A Modapp model3 is a key/value object that can be listened to for changes. It must have the following methods:
on(event, handler)
- Adds a callback handler for an event. Only defined model event ischange
off(event, handler)
- Removes a callback handler for an event.
Collection interface
A Modapp collection4 is an iterable object that can be listened to for changes. It must have the following methods:
on(event, handler)
- Adds a callback handler for an event. Defined collection events areadd
, andremove
off(event, handler)
- Removes a callback handler for an event.
ResClient and Modapp
ResClient has nothing to do with Modapp. However, since ResClient’s models and collections implement the interface defined by Modapp, any library that expects Modapp models and collections will work out of the box together with ResClient.
The component libraries used in the example implements these interfaces:
modapp-base-component
5 - basic components used to render simple or nested HTML elementsmodapp-resource-component
6 - components that can listen and react to events in models and collections
Note
The libraries are written with pure Javascript without any third party dependencies. They only have a few shared internal dependencies where Modapp itself is not one of them.
Loading dependencies
Often you wish to use a module bundler, such as Webpack, to load dependencies using CommonJS / AMD / ES6 modules. To simplify the Book Collection example, all dependencies are loaded as UMD bundles in HTML script tags:
<script src="https://cdn.jsdelivr.net/npm/resclient@latest/dist/resclient.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/modapp-base-component@latest/dist/modapp-base-component.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/modapp-resource-component@latest/dist/modapp-resource-component.min.js"></script>
In the javascript code, the class constructors can be retrieved from the global scope, like this:
const { Elem, Txt, Button, Input } = window["modapp-base-component"];
const { CollectionList, ModelTxt } = window["modapp-resource-component"];
const ResClient = resclient.default;
Note
Because ResClient is written as an ES6 module, its class constructor will be found under the global
resclient.default
property when using the UMD script build.
Initializing ResClient
To get data from Resgate, we need to create a ResClient instance. This can be done in many places, but in our example this is done directly inside the <script>
tag:
let client = new ResClient('ws://localhost:8080');
Getting a resource
Once we’ve created the ResClient instance, we can load the resources needed for our components:
client.get('library.books').then(books => {
/* Rendering of book list */
});
Rendering the list
When rendering the list of books, we use the CollectionList
component. It requires two arguments:
- Modapp collection to use as data source
- Component factory function that gets an item from the collection, and returns a Modapp component
new CollectionList(books, book => (
/* ... */
)).render(document.getElementById('books'));
As long as it is rendered, CollectionList
will listen for any updates on the collection. If a book is added or removed, the component will handle the change with a nice transition animation.
Building a DOM structure
Modapp components are pure Javascript, using no template system. In order to create complex DOM structures, we can use the Elem
component. An Elem
component can render a node tree that may contain other embedded components.
Looking at the incomplete component factory function in the previous section, we can have it return such an Elem
component for each book in the list:
book => new Elem(n =>
n.elem('div', { className: 'list-item' }, [
n.elem('div', { className: 'card shadow' }, [
/* ... */
])
])
)
Reactive text components
Some texts, such as the title or author of a book, may be changed due to events from Resgate, and the components need to be updated. For this, we use the ModelTxt
component. It requires two arguments:
- Modapp model to use as data source
- Callback function that takes the model and returns the text string to be displayed
new ModelTxt(book, book => book.author)
As long as it is rendered, ModelTxt
will listen for any changes to the model. Whenever there is a change, the component will call the callback function to see if the text has been modified. If modified, it will make a nice fading transition to the new text.
Note
While the components’
render
methods are seldom called explicitly, they will be called from within theElem
orCollectionList
component that contains them.
Conclusion
That’s it! Modapp Components works out of the box together with ResClient, keeping your client view synchronized in real-time with your backend, while doing so with nice transition animations between states.
This done with increased speed, less code, and fewer dependencies compared to the worlds more famous component systems. All we need now is just some improvements to the documentation ;) .
Enjoy using ResClient and Modapp components!