├── .gitignore ├── main.js ├── with-data.js ├── package.js ├── with-method-data.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .versions 2 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import withData from './with-data' 2 | import withMethodData from './with-method-data' 3 | 4 | export { 5 | withData, 6 | withMethodData 7 | } 8 | -------------------------------------------------------------------------------- /with-data.js: -------------------------------------------------------------------------------- 1 | import {createContainer} from 'meteor/react-meteor-data' 2 | 3 | export default function (getMeteorData, opts) { 4 | return function (ComposedComponent) { 5 | return createContainer(Object.assign({ getMeteorData }, opts), ComposedComponent) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'orionsoft:react-meteor-data', 3 | version: '0.1.5', 4 | summary: 'Fetch Meteor data in React using decorators', 5 | git: 'https://github.com/orionsoft/react-meteor-data', 6 | documentation: 'README.md' 7 | }) 8 | 9 | Package.onUse(function (api) { 10 | api.versionsFrom('1.4.1.1') 11 | api.use('ecmascript') 12 | api.use('underscore') 13 | api.use('react-meteor-data@0.2.9') 14 | api.mainModule('main.js') 15 | }) 16 | 17 | Package.onTest(function (api) { 18 | api.use('ecmascript') 19 | api.use('tinytest') 20 | api.use('orionsoft:react-meteor-data') 21 | // api.mainModule('react-meteor-data-tests.js') 22 | }) 23 | -------------------------------------------------------------------------------- /with-method-data.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {_} from 'meteor/underscore' 3 | 4 | export default function (getData) { 5 | return function (ComposedComponent) { 6 | return class Component extends React.Component { 7 | 8 | constructor (props) { 9 | super(props) 10 | this.state = { 11 | isLoading: true 12 | } 13 | } 14 | 15 | componentWillReceiveProps (nextProps) { 16 | if (!_.isEqual(this.props, nextProps)) { 17 | this.fetchData(nextProps) 18 | } 19 | } 20 | 21 | componentWillMount () { 22 | this.fetchData(this.props) 23 | } 24 | 25 | fetchData (props) { 26 | this.setState({isLoading: true}) 27 | getData(props, (error, response) => { 28 | this.setState({isLoading: false, response, error}) 29 | }) 30 | } 31 | 32 | render () { 33 | return 34 | } 35 | 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Meteor Data 2 | 3 | Fetch Meteor data in React using decorators 4 | 5 | Medium Post 6 | 7 | - [Using decorators to fetch Meteor data in React](https://medium.com/orionsoft/using-decorators-to-fetch-meteor-data-in-react-419a6869400c) 8 | - [Using Meteor methods on React components to fetch data](https://medium.com/orionsoft/using-meteor-methods-on-react-components-to-fetch-data-8f98431a6252) 9 | 10 | ### Installing 11 | 12 | Install the package 13 | 14 | ``` 15 | meteor add orionsoft:react-meteor-data 16 | ``` 17 | 18 | Install the babel decorator 19 | 20 | ``` 21 | npm install --save-dev babel-plugin-transform-decorators-legacy 22 | ``` 23 | 24 | Create or update the ```.babelrc``` file in the root of your app 25 | 26 | ```js 27 | { 28 | "plugins": [ 29 | "babel-plugin-transform-decorators-legacy" 30 | ] 31 | } 32 | ``` 33 | 34 | ### Example with publication 35 | 36 | ```js 37 | import React from 'react' 38 | import {Meteor} from 'meteor/meteor' 39 | import {withData} from 'meteor/orionsoft:react-meteor-data' 40 | import MyCollection from './my-collection' 41 | 42 | /** 43 | * Prop will be checked also in the container 44 | */ 45 | const propTypes = { 46 | itemId: React.PropTypes.string.isRequired, 47 | isLoading: React.PropTypes.bool, 48 | item: React.PropTypes.string 49 | } 50 | 51 | @withData(({itemId}) => { 52 | const handler = Meteor.subscribe('myPublication', itemId) 53 | const isLoading = !handler.ready() 54 | const item = MyCollection.findOne(itemId) 55 | return {isLoading, item} 56 | }) 57 | export default class Component extends React.Component { 58 | 59 | render () { 60 | if (this.props.isLoading) return 61 | return ( 62 |
63 | {this.props.item.name} 64 |
65 | ) 66 | } 67 | 68 | } 69 | 70 | Component.propTypes = propTypes 71 | ``` 72 | 73 | ### Example with method 74 | 75 | ```js 76 | import React from 'react' 77 | import {Meteor} from 'meteor/meteor' 78 | import {withMethodData} from 'meteor/orionsoft:react-meteor-data' 79 | 80 | /** 81 | * Prop will be checked also in the container 82 | */ 83 | const propTypes = { 84 | itemId: React.PropTypes.string.isRequired, 85 | isLoading: React.PropTypes.bool, 86 | item: React.PropTypes.string 87 | } 88 | 89 | @withMethodData(({itemId}, ready) => { 90 | Meteor.call('getItem', itemId, ready) 91 | }) 92 | export default class Component extends React.Component { 93 | 94 | render () { 95 | if (this.props.isLoading) return 96 | return ( 97 |
98 | {this.props.item.name} 99 |
100 | ) 101 | } 102 | 103 | } 104 | 105 | Component.propTypes = propTypes 106 | 107 | // On the server 108 | Meteor.methods({ 109 | 'getItem': function (itemId) { 110 | const item = Items.findOne(itemId) 111 | return {item} // objects returned in the method will be passed as props 112 | } 113 | }) 114 | ``` 115 | --------------------------------------------------------------------------------