Forked from MadLittleMods/App-react-flux-async-dependent-store-init.js
Last active
August 29, 2015 14:27
-
-
Save pyadav/4ea53db67001cb4468b3 to your computer and use it in GitHub Desktop.
Flux: Initialize from asynchronous storage with interdependent stores - `waitFor` async - The real solution to this problem would be to create a DAO/service to feed data into the store via actions.
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
import React from 'react'; | |
import SomeStore from '../stores/SomeStore'; | |
import AppActions from '../actions/AppActions'; | |
function gatherSomeStoreState(props, state) { | |
return { | |
myRandomNumber: SomeStore.getRandomNumber() | |
}; | |
} | |
export default class App extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
componentDidMount() { | |
SomeStore.addChangeListener(this._onSomeStoreChange.bind(this)); | |
// Initialize the application | |
AppActions.init(); | |
} | |
componentWillUnmount() { | |
SomeStore.removeChangeListener(this._onSomeStoreChange.bind(this)); | |
} | |
render() { | |
return ( | |
<div>{this.state.myRandomNumber}</div> | |
); | |
} | |
_onSomeStoreChange() { | |
this.setState(gatherSomeStoreState(this.props, this.state)); | |
} | |
} |
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
import AppDispatcher from '../dispatcher/AppDispatcher'; | |
import AppConstants from '../constants/AppConstants'; | |
import assign from 'object-assign'; | |
import Promise from 'bluebird'; | |
// Small deferred constructor from: https://github.com/petkaantonov/bluebird/blob/master/API.md#deferred-migration | |
function deferredPromise() { | |
var resolve, reject; | |
var promise = new Promise(function() { | |
resolve = arguments[0]; | |
reject = arguments[1]; | |
}); | |
return { | |
resolve: resolve, | |
reject: reject, | |
promise: promise | |
}; | |
} | |
import events from 'events'; | |
var EventEmitter = events.EventEmitter; | |
var CHANGE_EVENT = 'CHANGE_EVENT'; | |
var isInitializedDeferredPromise = deferredPromise(); | |
var maxSetting = 5; | |
var SettingsStore = assign({}, EventEmitter.prototype, { | |
getIsInitializedPromise: function() { | |
return isSettingsInitializedDeferredPromise.promise; | |
}, | |
getMaxSetting: function() { | |
return maxSetting; | |
}, | |
emitChange: function() { | |
this.emit(CHANGE_EVENT); | |
}, | |
addChangeListener: function(callback) { | |
this.on(CHANGE_EVENT, callback); | |
}, | |
removeChangeListener: function(callback) { | |
this.removeListener(CHANGE_EVENT, callback); | |
}, | |
dispatchToken: AppDispatcher.register(function(action) { | |
switch(action.actionType) { | |
case AppConstants.APP_INIT: | |
retrieveSettingsFromPersistantStorage() | |
.then(function() { | |
console.log('Settings Retrieved!'); | |
isInitializedDeferredPromise.resolve(true); | |
SettingsStore.emitChange(); | |
}) | |
.catch(function(e) { | |
console.log('Error retrieving playground settings:', e); | |
isInitializedDeferredPromise.reject(e); | |
}); | |
break; | |
case AppConstants.APP_SET_MAX_SETTING: | |
maxSetting = action.value; | |
savePersistently(); | |
SettingsStore.emitChange(); | |
break; | |
// Respond to other actions here | |
// ... | |
default: | |
// no op | |
} | |
// No errors. Needed by promise in Dispatcher. | |
return true; | |
}) | |
}); | |
function retrieveSettingsFromPersistantStorage() { | |
return new Promise(function (resolve, reject) { | |
// Pretend `localStorage` is asynchonous in this example | |
setTimeout(function() { | |
maxSetting = window.localStorage.getItem('maxSetting'); | |
resolve(true); | |
}, 2000); | |
}); | |
} | |
function savePersistently() { | |
window.localStorage.setItem('maxSetting', maxSetting); | |
} |
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
import AppDispatcher from '../dispatcher/AppDispatcher'; | |
import AppConstants from '../constants/AppConstants'; | |
import SettingsStore from '../stores/SettingsStore'; | |
import assign from 'object-assign'; | |
import events from 'events'; | |
var EventEmitter = events.EventEmitter; | |
var CHANGE_EVENT = 'CHANGE_EVENT'; | |
var SomeStore = assign({}, EventEmitter.prototype, { | |
// Returns a random number in this range: [0, SettingsStore.getMaxSetting()) | |
getRandomNumber: function() { | |
return Math.random() * SettingsStore.getMaxSetting(); | |
}, | |
emitChange: function() { | |
this.emit(CHANGE_EVENT); | |
}, | |
addChangeListener: function(callback) { | |
this.on(CHANGE_EVENT, callback); | |
}, | |
removeChangeListener: function(callback) { | |
this.removeListener(CHANGE_EVENT, callback); | |
}, | |
dispatchToken: AppDispatcher.register(function(action) { | |
switch(action.actionType) { | |
case AppConstants.APP_INIT: | |
// This isn't really necessary in this instance | |
// but is useful if perhaps SettingsStore needs to init some stuff | |
AppDispatcher.waitFor([ | |
SettingsStore.dispatchToken | |
]); | |
// Once the SettingsStore has all of the data loaded | |
// from persistent storage, update the processor | |
SettingsStore.getIsInitializedPromise() | |
.then(function() { | |
// Emit a change so the views will pick up the new values | |
// that will come from the settings being loaded | |
SomeStore.emitChange(); | |
}); | |
break; | |
// Respond to other actions here | |
// ... | |
default: | |
// no op | |
} | |
// No errors. Needed by promise in Dispatcher. | |
return true; | |
}) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment