Want to know how we built the front end for the touch screens at Visitor Center Joki? Our Technology Director Mikko guides you through our solution in his new blog post.
Some time ago, we implemented a set of digital services for Visitor and Innovation Center Joki. The impressive space showcases business life and city development in the area and can be rented by companies for all kinds of networking events.
Perhaps the most prominent part of our work is the digital info screen system that consists of three 42" touch screens whose main purpose is to serve as a digital showroom for local businesses. You can see how they look like in action from the video below:
The content served by the application needed to be editable but be flexible in its presentation. Typically this kind of content is represented in a relational database. But as this product needed maximal flexibility and we were responsible for curating and creating the content, it was evident that we could do a bit better.
When the project started in 2017, we had had good experiences with Clojure, having implemented backend solutions on top of it. We also had some experience in Clojurescript from the time we had created a set of internal tools and a web client for the taxi ordering app Valopilkku with it.
Datascript is an immutable database and Datalog query engine that is embeddable in a web page and provides a great base for implementing this kind of data architecture. We decided to rely on EDN (Extensible Data Notation) data for persisting our database. EDN is a collection of serialized Clojure data structures. The data can then be trivially sent over the wire, separated into multiple files that can be combined into a database by a CI pipeline, and served statically to the browser.
As an example, let's take a look at our own data from the disk:
There are many ways to organize this content, but the basic idea we used was that we deploy a graph data model, with :joki/id representing the type of the object and :joki/owner pointing to the owner of the object. We can transact these objects directly to the datascript database as datoms, and employ Datalog queries to get the data we are interested in. For instance, to get locations and the name for all the entries in the map view, we can just run:
To get the database up and working with Re-frame, we did the "dirty" approach and just embedded the whole DB inside the app-db, using the subscription mechanisms to run the actual queries and making the subscription tree a bit more efficient by triggering content reloads only when the related data had changed. For instance:
where db/parent-categories and db/assets-by-owners are defined as(defn parent-categories [db]
This works well in practice since we don't mutate the database while it is running; only the queries might change inputs over time. In more complicated situations, one can use Re-Posh to achieve a more elegant solution.
We were able to implement a fairly complicated frontend very easily using these technologies. The design has changed a lot since the initial conception but the data layer itself has remained pretty consistent – only the queries that we do to it might change a bit. We are currently using Clojurescript for many of our front end solutions, mainly incorporating tools such as Reagent, Re-Frame and Datascript to deliver rich user experiences for our end-user.
Naturally, there are a few things we might have done differently with our current experience using Clojurescript and Datascript. But all in all, the solution has served its purpose well and has been running steadily without much maintenance all this time.
Would you like to be a part of our team building the next wave of CLJS based products? Don't hesitate to contact us – we are hiring!