Last active
August 29, 2015 14:05
-
-
Save gaearon/3a3bfe0b8191cb3abcd7 to your computer and use it in GitHub Desktop.
Removing duplication from similar paginating Flux Stores
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
// Assumes you're using normalizr https://github.com/gaearon/normalizr | |
// --------------- | |
// Helpers: | |
// --------------- | |
// StoreUtils | |
'use strict'; | |
var EventEmitter = require('events').EventEmitter, | |
merge = require('react/lib/merge'), | |
CHANGE_EVENT = 'change'; | |
var StoreUtils = { | |
createStore(spec) { | |
var store = merge(EventEmitter.prototype, merge(spec, { | |
emitChange() { | |
this.emit(CHANGE_EVENT); | |
}, | |
addChangeListener(callback) { | |
this.on(CHANGE_EVENT, callback); | |
}, | |
removeChangeListener(callback) { | |
this.removeListener(CHANGE_EVENT, callback); | |
} | |
})); | |
store.setMaxListeners(0); | |
return store; | |
} | |
}; | |
module.exports = StoreUtils; | |
// PaginatedList.js | |
'use strict'; | |
var _ = require('underscore'), | |
invariant = require('react/lib/invariant'); | |
class PaginatedList { | |
constructor(items) { | |
this._items = items || []; | |
this._pageCount = 0; | |
this._isExpectingPage = false; | |
} | |
getAll() { | |
return this._items; | |
} | |
getPageCount() { | |
return this._pageCount; | |
} | |
isExpectingPage() { | |
return this._isExpectingPage; | |
} | |
expectPage() { | |
invariant(!this._isExpectingPage, 'Cannot call expectPage twice without prior cancelPage or receivePage call.'); | |
this._isExpectingPage = true; | |
} | |
cancelPage() { | |
invariant(this._isExpectingPage, 'Cannot call cancelPage without prior expectPage call.'); | |
this._isExpectingPage = false; | |
} | |
receivePage(newItems) { | |
invariant(this._isExpectingPage, 'Cannot call receivePage without prior expectPage call.'); | |
if (newItems.length) { | |
this._items = _.union(this._items, newItems); | |
} | |
this._isExpectingPage = false; | |
this._pageCount++; | |
} | |
} | |
module.exports = PaginatedList; | |
// PaginatedStoreUtils.js | |
'use strict'; | |
var StoreUtils = require('./store_utils'), | |
StampStore = require('stores/stamp_store'), | |
UserStore = require('stores/user_store'), | |
ZineStore = require('stores/zine_store'), | |
AppDispatcher = require('dispatcher/app_dispatcher'), | |
PaginatedList = require('utils/paginated_list'), | |
invariant = require('react/lib/invariant'), | |
createStore = StoreUtils.createStore; | |
var CONTENT_STORES = [ | |
StampStore.dispatchToken, | |
UserStore.dispatchToken, | |
ZineStore.dispatchToken | |
]; | |
var PaginatedStoreUtils = { | |
createPaginatedStore({ | |
request: requestAction, | |
error: errorAction, | |
success: successAction | |
}) { | |
invariant(requestAction, 'Pass a valid request action.'); | |
invariant(errorAction, 'Pass a valid error action.'); | |
invariant(successAction, 'Pass a valid success action.'); | |
var list = new PaginatedList(), | |
store, | |
handler; | |
store = createStore({ | |
getAll() { | |
return list.getAll(); | |
}, | |
getPageCount() { | |
return list.getPageCount(); | |
}, | |
isFetching() { | |
return list.isExpectingPage(); | |
} | |
}); | |
handler = function (payload) { | |
var action = payload.action; | |
switch (action.type) { | |
case requestAction: | |
list.expectPage(); | |
break; | |
case errorAction: | |
list.cancelPage(); | |
break; | |
case successAction: | |
AppDispatcher.waitFor(CONTENT_STORES); | |
list.receivePage(action.response.result.objects); | |
break; | |
} | |
store.emitChange(); | |
}; | |
return { | |
store: store, | |
handler: handler | |
}; | |
}, | |
}; | |
module.exports = PaginatedStoreUtils; | |
// --------------- | |
// Usage: | |
// --------------- | |
// FeedStampStore.js | |
'use strict'; | |
var AppDispatcher = require('../dispatcher/app_dispatcher'), | |
AppConstants = require('../constants/app_constants'), | |
PaginatedStoreUtils = require('utils/paginated_store_utils'), | |
createPaginatedStore = PaginatedStoreUtils.createPaginatedStore, | |
ActionTypes = AppConstants.ActionTypes; | |
var actions = { | |
request: ActionTypes.REQUEST_FEED_STAMPS, | |
error: ActionTypes.HANDLE_FEED_STAMPS_ERROR, | |
success: ActionTypes.RECEIVE_FEED_STAMPS | |
}; | |
var { | |
store: FeedStampStore, | |
handler | |
} = createPaginatedStore(actions); | |
AppDispatcher.register(handler); | |
module.exports = FeedStampStore; | |
// AboutZineStore.js | |
'use strict'; | |
var AppDispatcher = require('../dispatcher/app_dispatcher'), | |
AppConstants = require('../constants/app_constants'), | |
PaginatedStoreUtils = require('utils/paginated_store_utils'), | |
createPaginatedStore = PaginatedStoreUtils.createPaginatedStore, | |
ActionTypes = AppConstants.ActionTypes; | |
var actions = { | |
request: ActionTypes.REQUEST_ABOUT_ZINES, | |
error: ActionTypes.HANDLE_ABOUT_ZINES_ERROR, | |
success: ActionTypes.RECEIVE_ABOUT_ZINES | |
}; | |
var { | |
store: AboutZineStore, | |
handler | |
} = createPaginatedStore(actions); | |
AppDispatcher.register(handler); | |
module.exports = AboutZineStore; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment