---
title: The JS model layer
teaser: 'The JS-Model library enables you to persist state in your Javascript applications.

  '
tags: javascript,new bamboo,web
author: Max Williams
published_on: 2010-03-08
---

_This post was originally published on the New Bamboo blog, before [New Bamboo
joined thoughtbot in London][new-bamboo-thoughtbot]._

---

## Adding a Model layer to your Javascript

To build the best possible JS RIA, we need to build a data or model layer. This
needs to be handled in a way which goes beyond simply embedding the data in the
HTML, and also beyond relying on simple collections of hashes and arrays.

A web server needs to send data to the client, as part of an initial "platform"
which the client can build up the UI and behaviour from. A client therefore
holds onto and manages this snapshot of "state" which it has received from the
server.

The lifecycle of these data objects need to be managed on the client end,
persisting the state (when necessary) as part of the process. A "state manager"
needs to work with collections of objects, which can be manipulated locally and
bound to the UI.

[js-model] is our solution to this. It should feel straightforward and familiar
to you - particularly if you're used to ActiveRecord and its ilk.

## Not another REST proxy

A really important point to note at the outset is that this is not a simple
"proxy" to the "real" models on the server. It is not a glorified REST-client,
and hence, retrieving objects is done from the constantly updated local
collection, and not over HTTP.

JS-model is a library for **dealing with models in your Javascript** - a subtle
difference from being a REST-client, and one that's easy to overlook the
importance of.

To put it another way, we need to appoint it responsibility for [maintaining the
state] of objects for the duration of the page view.

## Moving Beyond Arrays

Getting data into the browser isn't difficult, especially with the prevalence of
JSON (how did we live without it?!). But having the data itself is just the
first step and beyond the most simple of applications things start to get
increasingly unmanageable.

## Persistence

By default JS model only persists objects within the context of the page being
viewed. Perhaps you're displaying data from a Twitter feed or maybe you're
sending and receiving data through a WebSocket (chat perhaps). In both cases you
might not care about keeping the data beyond the page view but having the
ability to work with models and collections is a convenience at the very least.

### REST

As a design constraint, to persist using REST means explicitly adding a REST
adaptor at the time of class creation.

```javascript
var Project = Model("project", {
  persistence: Model.RestPersistence("/projects")
})
```

In the most common usage, you read data, manipulate it and send it back to the
server using Ajax and JSON. In the old days we'd be tempted to send back
snippets of rendered HTML back to an essentially dumb client (RJS) but nowadays
that's not good enough. We need data.

Our websites are evolving towards the level of desktop apps where an
ever-increasing amount of functionality is performed in the browser. Our
client-side code operates on this data reflecting changes in the view.

It would be equally possible to add local storage to your models instead. You
can even mix and match between some data which need to only persist locally, and
others which need to go via REST.

## Convention-based event-triggering

There are common patterns to the lifecycle of data objects on the client side
and these can be listened to by your UI. Objects are created, updated and
destroyed, and these actions need to be reflected in the UI.

JS-model gives you hooks to link to adding and removing from a collection, and
others linked to changes in state in individual objects. This becomes immensely
powerful as a means of structuring UI behaviour.

## Updating state from elsewhere

If state is held on the browser, there is a possibility that another user is
making this state stale by interacting independently with the server. This
highlights the increased complexity a manager of client objects needs to have.

We can alleviate the problem by adding websockets into the mix, and using an
[event based convention] to update our JS models whenever necessary.

## RTFM

Much of the detail has been glossed over in this post to allow for some bigger
picture discussion. However, the [js model documentation] on Github has some
more in-depth examples, which we will be expanding further going forward.

[event based convention]: https://thoughtbot.com/blog/json-event-based-convention-websockets
[js model documentation]: http://benpickles.github.com/js-model/
[js-model]: http://github.com/benpickles/js-model
[maintaining the state]: https://thoughtbot.com/blog/let-them-eat-state
[new-bamboo-thoughtbot]: https://thoughtbot.com/blog/new-bamboo-joins-thoughtbot-in-london
