Last active
December 8, 2016 11:50
-
-
Save richnicholls404/f078d95cab9095e5231e9cfaee761c8d to your computer and use it in GitHub Desktop.
Store a Meteor Collection in Redux
This file contains hidden or 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 { combineReducers, dispatch } from 'redux'; | |
import * as '_' from 'lodash'; | |
//globals: SubsManager | |
import { MyCollection } from './MyCollection'; | |
// queue initial data load, otherwise you could be making 1000s of pointless immutable objects | |
const queuedState = {}; | |
// watch changes to the collection. Save changes before ready to a queue, otherwise dispatch action on store | |
MyCollection.find().observeChanges({ | |
// added events | |
added(id, fields) { | |
// add to queued state if collection is not ready yet | |
if (!SubsManager.ready()) { | |
if (queuedState[MyCollection.name] === undefined) { | |
queuedState[MyCollection.name] = {}; | |
} | |
queuedState[MyCollection.name][id] = fields; | |
} | |
//else add to state | |
else { | |
dispatch({ | |
type: 'ADD_DATA', | |
payload: { | |
id, | |
fields, | |
collectionName: MyCollection.name | |
} | |
}); | |
} | |
}, | |
// changed events | |
changed(id, fields) { | |
if (!SubsManager.ready()) { //unlikely? impossible? | |
queuedState[MyCollection.name][id] = fields; | |
} | |
else { | |
dispatch({ | |
type: 'CHANGE_DATA', | |
payload: { | |
id, | |
fields, | |
collectionName: MyCollection.name | |
} | |
}); | |
} | |
}, | |
// removed events | |
removed(id) { | |
if (!SubsManager.ready()) { //unlikely? impossible? | |
delete queuedState[MyCollection.name][id]; | |
} | |
else { | |
dispatch({ | |
type: 'REMOVE_DATA', | |
payload: { | |
id, | |
collectionName: MyCollection.name | |
} | |
}); | |
} | |
} | |
}); | |
// wait for collection to be ready before adding queue | |
Tracker.autorun(() => { | |
if (SubsManager.ready()) { | |
dispatch({ | |
type: 'PROCESS_QUEUED_DATA', | |
payload: { | |
queuedData: queuedData | |
} | |
}); | |
} | |
}); | |
// reducer | |
function dataStorageReducer(state = {}, action) { | |
switch (action.type) { | |
// add data - put it straight in | |
case ADD_DATA: | |
return _.defaultsDeep({}, { | |
[action.payload.collectionName]: { | |
[action.payload.id]: action.payload.fields | |
} | |
}, state); | |
// change data - you'll only get the updated fields, so merge with the data we already have | |
case CHANGE_DATA: | |
const oldData = _.getIn(state, [action.payload.collectionName, action.payload.id]); | |
const newData = _.defaults(fields, oldData); | |
return _.defaultsDeep({}, { | |
[action.payload.collectionName]: { | |
[action.payload.id]: newData | |
} | |
}, state); | |
// remove data - just get rid of it | |
case REMOVE_DATA: | |
return _.unset( | |
_.defaultsDeep({}, state), [action.payload.collectionName, action.payload.id] | |
); | |
// queued data - just put it in | |
case 'PROCESS_QUEUED_DATA': | |
return _.defaultsDeep({}, action.payload.queuedData); | |
default: | |
return state; | |
} | |
} | |
// register reducer | |
const todoApp = combineReducers({ | |
dataStorageReducer | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment