Upcoming Features in Meteor Blaze

What we’re building now, and where Meteor’s front-end framework is going

Sashko Stubailo

--

Meteor is a full-stack JavaScript web and mobile application platform. One of its standout features is reactivity across all layers of the stack. This means that when you make a change in the database, that change propagates through a persistent client-server connection and triggers an automatic update of the user interface, with no “glue” code necessary.

Blaze is the top of that stack — the front-end rendering engine that lets you define what your page should look like via HTML-like templates and then hook up data from Minimongo, Meteor’s front-end data store.

The last big story on Meteor’s front-end was the release of Blaze in Meteor 0.8. It was a huge improvement in performance and features over the previous rendering engine, enabling Meteor to update only the smallest necessary part of the DOM on every data change. That was a while ago — what’s the next big thing?

Reusable, cross-platform, full-stack user interface components

Meteor is in a unique position among other frameworks such as Angular and React because it covers both client and server, and even includes a build system. This means a UI component system can take advantage of functionality across the entire stack: pre-compile template code, interact with server-side data, and trigger native APIs in Meteor’s built in PhoneGap integration all at once. We hope that eventually, any functionality can be added to a Meteor app through packages that bundle self-contained, full-featured UI building blocks. One current example is the accounts-ui package, which includes everything you need for an accounts system across client and server. All you have to do is decide where it should go on the page.

Sneak Peek at Upcoming APIs for Templates

Templates are the building blocks of every Meteor app that uses the Blaze rendering engine. A template is a chunk of HTML code with special Spacebars directives to add logic, along with a set of callbacks, helpers, and event handlers. Our plan is to continually improve the Blaze template system with more capabilities that will let templates be more easily used as self-contained chunks of app functionality.

Below is just a preview of what we have been thinking about — the APIs or features might change before they make it into an official Meteor release. Keep in mind that since we’re past Meteor 1.0, all of our changes will be backwards-compatible until Meteor 2.0. This means you’ll be able to use the old style or the new style depending on your preference.

Template-Level Subscriptions

The folks at Discover Meteor recently wrote a great blog post about a new pattern where each template in your app subscribes to the data it needs. With this pattern, you don’t have to predict from 1000 miles away which data everything on your page needs. You just include the template that displays the data you want to show, and the template handles subscribing to the data automatically.

Currently, this pattern requires a lot of manual management of subscriptions, so we wanted to make it simple.

Current:

Template.calendar.created = function () {
// Save the subscription handle
this.subHandle = Meteor.subscribe("events");
};
Template.calendar.helpers({
// Make a helper for ready state
dataReady: function () {
return Template.instance().subHandle.ready();
}
})
Template.calendar.destroyed = function () {
// Make sure the data goes away when we don’t need it anymore
this.subHandle.stop();
};
<template name="calendar">
{{#if dataReady}}
… show events …
{{else}}
Loading…
{{/if}}
</template>

Planned:

Template.calendar.onCreated(function () {
// Just subscribe, stopping the subscription is handled
// automatically
this.subscribe("events");
});
<template name="calendar">
{{#if Template.subscriptionsReady}}
… show events …
{{else}}
Loading…
{{/if}}
</template>

We are adding a template-specific subscription method that automatically stops subscriptions when the template is removed from the page. There will also be a built-in helper, Template.subscriptionsReady, that returns true when all of the subscriptions for your template are ready. This should make using template-level subscriptions much more pleasant!

Built-in Local Template State

There’s a great pattern people are adopting where they attach ReactiveVars to the template instance to keep track of local state instead of using Session to store everything. I love this pattern because it means there is less global state and your templates can’t get entangled between themselves by accidentally sharing Session keys. On the other hand, this can be a little more cumbersome because you have to manually declare a lot of variables, and you lose the capability of Session to automatically persist across hot code push, making it annoying to develop components with internal state.

To help with this, we’re going to introduce a built-in vars dictionary on every template instance that acts just like Session, but on a per-template basis. If you pass your template a unique ID, vars will automatically serialize itself across hot code push.

Current:

Template.calendar.created = function () {
// Declare some temporary state
this.selectedDay = new ReactiveVar(new Date());
this.viewStyle = new ReactiveVar("month");
};
Template.calendar.helpers({
// Declare a helper for each one
selectedDay: function () {
return Template.instance().selectedDay.get();
},
viewStyle: function () {
return Template.instance().viewStyle.get();
}
});

Planned:

Template.calendar.onCreated(function () {
// Declare some temporary state
this.vars.setDefault("selectedDay", new Date());
this.vars.setDefault("viewStyle", “month”);
});
// No need to define helpers, just use
// {{Template.vars.selectedDay}}

As people start storing more of their data inside the designated vars object, we will keep adding more features for better template state management. Hopefully it will be just as easy to use this new feature as it was to use Session for everything.

Each-in

Data flow through Blaze templates is done through a concept called the data context. Each DOM node has its own data context, which is a result of a template inclusion or block helper above it in the view tree. The data context is the set of data that can be accessed with curly braces inside that element.

Until now, whenever you used {{#each}}, you would mask the enclosing data context — inside the each block, you would only have access to one item of the collection you passed to #each. This made it very annoying to access data inside double nested #each blocks. The new syntax for each will make these situations much nicer.

Current:

{{#each teams}}
{{#each people}}
{{name}} is on team {{../name}}
{{/each}}
{{/each}}

Planned:

{{#each team in teams}}
{{#each person in people}}
{{person.name}} is on team {{team.name}}
{{/each}}
{{/each}}

I think the second example is much clearer about whose names are being displayed.

The Future

This is but a small part of our plans for improving Blaze in the coming months, and we’re in the middle of active discussions and research. If you have any ideas about new Blaze features that will streamline your development experience, give us a shout at our GitHub page!

--

--

Sashko Stubailo

engineer at @stripe. previously open source eng manager at @apollographql and @meteorjs, https://github.com/stubailo