My experience with ViewModel (Meteor)

Late last year I finally decided to take some time off from work and start building a personal project I’d been sitting on for months. Meteor was my weapon of choice for a number of reasons, which are not relevant to this story.

At the time everyone was suddenly jumping off Meteor’s de-facto rendering library, Blaze, like it was a sinking ship and switching over to React. To me React always just seemed like a whole lot of boilerplate for nothing special in return, so I wasn’t immediately ready to follow the hordes over to Facebook’s lair.

After a few days of researching my options between Blaze, Angular, React, Vue and a couple of others, I stumbled across ViewModel. I read through the documentation, but was left puzzled. I had a hard time understanding the core idea behind ViewModel or it’s benefits compared to anything else. I closed my browser tab and sighed, moving on to exploring the next dozen or so packages providing some kind of syntactic sugaring on top of Blaze, each trying to fix a subset of the same issues with slightly different tricks.

By then I had already started building my project with plain Blaze, just to get something started. Life was good for a while, until lines of code started to add up. One day, while slightly frustrated and browsing the Meteor Forums for some inspiration, I stumbled across a post from the creator of ViewModel.

manuel: I was going to define view models, how they work, why they make life so much easier, etc. but I think it’s better if you experience it yourself. Take a relatively small part of one of your websites (a template with blaze, template/controller with Angular, or component with React) and re-write it using ViewModel.

I was getting increasingly annoyed by the quirks in Blaze, so I decided to give ViewModel one more chance and do as I’m told. Then and there I rewrote a part of my project. Some hours later I felt enlightened.

What happened?

  • My view-related code became considerably easier to read and follow
  • The amount of lines of code needed was a lot smaller. By a lot I mean approximately 50 percent or more, which is crazy
  • I could give up reading the Blaze documentation over and over again (where’s that damn template instance!)
// In ViewModel we can do this
Template.example.viewmodel({
randomHelper() {
let instance = this.templateInstance;
}
});
  • Sharing state or data between components was suddenly easy
ViewModel.share({
bookshelf: {
selectedBook: null
}
});
Template.bookSelect.viewmodel({
share: 'bookshelf',
  select(book) {
this.selectedBook(book);
}
});
Template.showBook.viewmodel({
share: 'bookshelf',

chosenBook() {
return this.selectedBook();
}
});
  • I no longer needed to invent awkward id- or class-definitions for HTML-elements…
// Blaze
<button class="js-control-handle-fancy-button ui primary button">
// ViewModel
<button {{b "ref: fancyButton"}} class="ui primary button">
  • …which also cleans up your Template-code
// Blaze
$('.js-control-handle-fancy-button').doSomething()
// ViewModel
this.fancyButton.doSomething()
  • A couple of unresolved bugs just magically disappeared
  • Event handling became a breeze with ViewModel bindings
<button {{b "click: doSomething()"}}>Press me</button>
  • Mixins allowed me to easily reuse lots and lots of code
  • I got some nice features for free, like automatically saved state on hot code push
  • I got carried away by the rapid speed of development and created a bunch of extra features just for the fun of it

All this happened while I was just learning ViewModel. The idea of removing until there’s nothing more to remove seems to work especially well with Meteor and Blaze. When I started to understand ViewModel, I could appreciate how simple it is, yet providing so much on top of Blaze. The idea behind ViewModel is actually summarized quite nicely in this quote from ViewModel.org:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

Blaze, but better

While building a real world app using Meteor, I’d quite often run into problems that are more or less unique to Meteor and Blaze. Tricks I used to know didn’t necessarily work anymore. I’d struggle at first, just to find out that one of ViewModel’s nifty features, such as Signals, would solve exactly the problem I was facing, thus making my life just that much easier as a developer.

To me it feels like Blaze is incomplete without ViewModel and I cannot understand why ViewModel is not recommended or even mentioned in the Meteor Guide. It brings all the good stuff about Angular, React, Vue or similar frameworks/libraries to Meteor with zero hassle or setup. It just works and keeps out of your way.

Blaze is not dead (I hope)

With interesting new projects being created around Blaze, like blaze-modules, I’ve observed quite a few developers falling in love with Blaze again. I really hope that the community driven Blaze picks up, enabling nice new things like server-side rendering in the future.

Reliability

The few bugs in ViewModel 2.x I’ve encountered have been fixed within a couple of days, sometimes in hours, after posting them on Github. ViewModel is basically built by one man, but it’s used by so many that I have a lot faith in the continuity and maintenance of the project.

When comparing React and Blaze+ViewModel, I can’t help but notice the similarities. ViewModel just seems to be missing all the boilerplate and hard-to-remember naming conventions.

Insurance

If it ever comes down to that, converting the view layer from ViewModel to React shouldn’t be too big of a task, given that the early React-version of ViewModel already exists.

Final words

Really, it’s best to try it out and see for yourself. In my opinion, ViewModel doesn’t get half the attention it deserves, and I hope to help fix that by sharing my experiences.