Created
November 7, 2014 21:36
-
-
Save dandelany/83c9c4d53ca39e4550b6 to your computer and use it in GitHub Desktop.
Fluxxor flux-client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Fluxxor = require('fluxxor'); | |
var _ = require('underscore'); | |
// A FluxClient is a special Fluxxor.Store constructor that is a wrapper around a 'client' object. | |
// Client objects are generally an object containing all the server calls your app can make | |
// FluxClient allows you to listen for Fluxxor actions and cause them to trigger requests in the client, | |
// this way your actions can remain pure and don't have to call the client directly. | |
// It can also dispatch Fluxxor actions when the client request begins and upon request success/failure | |
// createFluxClient creates a FluxClient constructor from two arguments: | |
// 1. an asynchronous client object, which is an object containing methods of the form: | |
// loadSomething(options, success, fail) (all three args required) | |
// options is an arbitrary object which will be passed through from the 'on' action payload | |
// success is a callback which the client must call upon success | |
// fail is a callback which the client must call upon failure | |
// 2. a spec that describes which Fluxxor actions should trigger which client calls, and (optionally) actions which | |
// should be dispatched upon the asynchronous request's start, success, and failure. | |
// This spec should be an object containing keys which match the names of methods on the client object (arg 0) | |
// of the form: { | |
// loadSomething: { | |
// on: constants.LOAD_SOMETHING, // required, action which triggers call to client | |
// start: constants.LOADING_SOMETHING, // optional | |
// success: constants.LOADED_SOMETHING, // optional | |
// fail: constants.LOAD_SOMETHING_FAILED // optional | |
// } | |
// } | |
var createFluxClient = function(client, spec) { | |
var actions = {}, | |
actionHandlers = {}; | |
_.each(spec, function(methodSpec, methodName) { | |
if(!_.isFunction(client[methodName])) { | |
throw new Error("Client method " + methodName + " provided in spec, but not found in client."); | |
} else if(_.isUndefined(methodSpec.on)) { | |
throw new Error("client spec for " + methodName + "must provide an 'on' action which triggers it"); | |
} | |
var handlerName = ["handle", methodSpec.on].join('_'); | |
actions[methodSpec.on] = handlerName; | |
actionHandlers[handlerName] = function(payload) { | |
payload = payload || {}; | |
var dispatcher = this.flux.dispatcher; | |
var success = methodSpec.success ? _.bind(function(response) { | |
var successPayload = _.extend(_.clone(payload), {response: response}); | |
dispatcher.dispatch({type: methodSpec.success, payload: successPayload}); | |
}, this) : function(){}; // `this` is store | |
var fail = methodSpec.fail ? _.bind(function(response) { | |
var failPayload = _.extend(_.clone(payload), {response: response}); | |
dispatcher.dispatch({type: methodSpec.fail, payload: failPayload}); | |
}, this) : function(){}; | |
var request = client[methodName](payload, success, fail); | |
if(methodSpec.start) { | |
setTimeout(_.bind(function() { | |
var startPayload = _.extend(_.clone(payload), {request: request}); | |
dispatcher.dispatch({type: methodSpec.start, payload: startPayload}); | |
}, this), 0); | |
} | |
}; | |
}); | |
var storeSpec = { actions: actions }; | |
_.extend(storeSpec, actionHandlers); | |
var FluxClient = Fluxxor.createStore(storeSpec); | |
return FluxClient; | |
}; | |
if( typeof module !== "undefined" && ('exports' in module)) { | |
module.exports = createFluxClient; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you have an example of its usage?