A Reactive Data Architecture
for JavaScript Frontends
Twitter @youyuxi / GitHub @yyx990803
We've gotten pretty good at dealing with this...
But how about this?
Flux Stores ?
Trouble with non-conventional APIs
Difficulty managing optimistic updates
Pull-centric design leads to imperative code
Relay / GraphQL
Falcor / JSON Graph
Om Next
Unfortunately, none of these are ready yet...
var light = new ReactiveVar('green');
Tracker.autorun(function() {
console.log('The light is', light.get());
});
light.set('amber');
light.set('red');
// Result:
> 'The light is green'
> 'The light is amber'
> 'The light is red'
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
Template.body.helpers({
// reactive helper function
// just return what you need
tasks: function () {
return Tasks.find({});
}
});
}
<ul>
{{#each tasks}}
<li>{{text}}</li>
{{/each}}
</ul>
// define a data updating method on server
Meteor.methods({
addTask: function (text) {
// Make sure the user is logged in before inserting a task
if (! Meteor.userId()) {
throw new Meteor.Error("not-authorized");
}
Tasks.insert({
text: text,
createdAt: new Date(),
owner: Meteor.userId(),
username: Meteor.user().username
});
}
});
// calling it from client, as easy as:
Meteor.call("addTask", text);
Template.notifications.onCreated(function () {
// Use this.subscribe inside onCreated callback
this.subscribe("notifications")
})
<template name="notifications">
{{#if Template.subscriptionsReady}}
<!-- This is displayed when all data is ready. -->
{{#each notifications}}
{{> notification}}
{{/each}}
{{else}}
Loading...
{{/if}}
</template>
meteor add urigo:angular
meteor add react
angular.module("simple-todos", ['angular-meteor']);
angular.module("simple-todos")
.controller("TodosListCtrl", ['$scope',
function($scope){
$scope.tasks = [...];
}
]);
<ul ng-repeat="task in tasks">
<li>{{task.text}}</li>
</ul>
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
angular.module("simple-todos", ['angular-meteor']);
angular.module("simple-todos")
.controller("TodosListCtrl", ['$scope', '$meteor',
function($scope, $meteor){
$scope.tasks = $meteor.collection(Tasks);
}
]);
}
<ul ng-repeat="task in tasks">
<li>{{task.text}}</li>
</ul>
var App = React.createClass({
getInitialState() {
return {
tasks: [...]
};
},
render() {
return (
<ul>
{this.state.tasks.map(function (task) {
return <li key={task._id}>{task.content}</li>;
})}
</ul>
);
}
});
var Tasks = new Mongo.Collection("tasks");
var App = React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
// This method knows how to listen to Meteor's
// reactive data sources, such as collection queries
return {
// Return an array with all items in the collection
tasks: Tasks.find().fetch()
};
},
render() {
return (
<ul>
{this.data.tasks.map(function (task) {
return <li key={task._id}>{task.content}</li>;
})}
</ul>
);
}
});