Skip to content

Commit

Permalink
Rewrite using redux middleware to decouple action with collection
Browse files Browse the repository at this point in the history
  • Loading branch information
nqbao committed May 30, 2016
1 parent e10999a commit a6d180e
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 15 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ The goal of this exploration is to propose an integration approach that:
* https://medium.com/modern-user-interfaces/how-we-redux-part-1-introduction-18a24c3b7efe
* https://subvisual.co/blog/posts/79-a-bridge-between-redux-and-meteor
* https://atmospherejs.com/meteor/react-meteor-data


* https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.ry4qjvhng
25 changes: 17 additions & 8 deletions imports/actionCreators.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ import { Meteor } from 'meteor/meteor';
import { createAction } from 'redux-actions';
import Tasks from './api/tasks/collection';

export const ADD_TODO = 'ADD_TODO';
export const addTodo = text => dispatch => {
dispatch({ type: ADD_TODO, payload: { text } });
Tasks.insert({ text });
const createMeteorAction = (type, payloadTransfomer, meteorMeta) => (...args) => dispatch => {
dispatch({
type,
payload: payloadTransfomer ? payloadTransfomer(...args) : args[0],
meta: {
meteor: meteorMeta
}
});
};

const createCollectionAction = (collection, type, payloadTransfomer) =>
createMeteorAction(type, payloadTransfomer, {
collection: typeof collection === 'object' ? collection._name : collection
});

export const ADD_TODO = 'ADD_TODO';
export const addTodo = createCollectionAction(Tasks, ADD_TODO, (text) => ({ text }));

export const REMOVE_TODO = 'REMOVE_TODO';
export const removeTodo = id => dispatch => {
dispatch({ type: REMOVE_TODO, payload: { id } });
Tasks.remove(id);
};
export const removeTodo = createCollectionAction(Tasks, REMOVE_TODO);

export const TOGGLE_TODO = 'TOGGLE_TODO';
export const toggleTodo = id => dispatch => {
Expand Down
4 changes: 2 additions & 2 deletions imports/components/app.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { Component } from 'react';
import { compose } from 'recompose';
import meteorSubscribe from '../lib/subscribe';
import { compose } from 'recompose';;
import { connect } from 'react-redux'
import { toggleVisibilityFilter } from '../actionCreators';
import Tasks from '../api/tasks/collection';
import meteorSubscribe from '../lib/subscribe'
import cursorListener from '../lib/cursorListener';

import TaskList from './list';
Expand Down
25 changes: 25 additions & 0 deletions imports/lib/meteorMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function getCollectionByName(name) {
return global.Meteor.connection._mongo_livedata_collections[name];
}

const meteorMiddleware = store => next => action => {
const meta = action.meta;
const payload = action.payload;

if (meta && meta.meteor) {
if (meta.meteor.collection) {
const collection = getCollectionByName(meta.meteor.collection);

// check if this is a meteor collection action
if (/REMOVE_/.test(action.type)) {
collection.remove(payload.id);
} else if (/ADD_/.test(action.type)) {
collection.insert(payload);
}
}
}

return next(action);
};

export default meteorMiddleware;
4 changes: 2 additions & 2 deletions imports/lib/subscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const meteorSubscribe = (factory, onReady) => {
let options;
let returnOptions = factory;

if (typeof subscription === 'function') {
returnOptions = subscription(this.props);
if (typeof returnOptions === 'function') {
returnOptions = returnOptions(this.props);
}

if (typeof returnOptions === 'string') {
Expand Down
3 changes: 2 additions & 1 deletion imports/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import thunk from 'redux-thunk';
import promise from 'redux-promise';
import createLogger from 'redux-logger';
import todoApp from './reducers';
import meteorMiddleware from '../lib/meteorMiddleware';

const logger = createLogger();

const store = createStore(
todoApp,
applyMiddleware(thunk, promise, logger)
applyMiddleware(thunk, promise, logger, meteorMiddleware)
);

export default store;

0 comments on commit a6d180e

Please sign in to comment.