Skip to content

Instantly share code, notes, and snippets.

@clalimarmo
Created March 1, 2016 23:25
Show Gist options
  • Save clalimarmo/f6b382db8595cfa1805c to your computer and use it in GitHub Desktop.
Save clalimarmo/f6b382db8595cfa1805c to your computer and use it in GitHub Desktop.
subscribable wrapper for falcor models, for reactive components
const falcor = require('falcor');
const Rx = require('rxjs');
//FalcorSubscribableModel
module.exports = function(modelOptions) {
modelOptions = modelOptions || {};
const self = {};
const modelSubject = new Rx.BehaviorSubject();
modelOptions.onChange = function() {
modelSubject.next(self.model);
};
self.model = new falcor.Model(modelOptions).batch(30);
self.subscribe = function(path, ...subscriptionArgs) {
const stream = modelSubject.flatMap(() => {
return Rx.Observable.fromPromise(self.model.get(path));
}).filter((response) => {
return response != null;
});
const subscription = stream.subscribe(...subscriptionArgs);
self.get(path);
return subscription;
};
self.call = function(...args) {
return self.model.call(...args).then((response) => {
//hack: falcor.Model operations don't do anything unless a "then" is specified
return response;
});
};
self.set = function(...args) {
return self.model.set(...args).then((response) => {
//hack: falcor.Model operations don't do anything unless a "then" is specified
return response;
});
};
self.get = function(...args) {
return self.model.get(...args).then((response) => {
//hack: falcor.Model operations don't do anything unless a "then" is specified
return response;
});
};
Object.freeze(self);
return self;
};
//usage - would like to reduce boilerplate
/*
const blogModel = require('./blog-model');
const BlogPost = React.createClass({
propTypes: {
postId: React.PropTypes.number.isRequired,
}
componentWillMount: function() {
this.setupSubscription(this.props.postId);
},
componentWillReceiveProps: function(newProps) {
this.setupSubscription(newProps.postId)
},
componentWillUnmount: function() {
this.cleanupSubscription();
},
setupSubscription: function(postId) {
this.cleanupSubscription();
this.subscription = blogModel.subscribe([
'postsById', postId, [
'title',
'body',
'author',
],
], (response) => {
this.setState({
title: response.json.postsById[postId].title,
body: response.json.postsById[postId].body,
author: response.json.postsById[postId].author,
});
});
},
cleanupSubscription: function() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
render: function() {
return (
<article>
<header>{this.state.title}</header>
<p>{this.state.body}</p>
<p>by {this.state.author}</p>
</article>
);
},
});
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment