Search code examples
javascriptmeteorreact-nativeecmascript-6ddp

Reactive usage of "inProgress-team/react-native-meteor" in Meteor 1.3


I have a project in react-native (0.23) with Meteor 1.3 as back-end and want to display a list of contact items. When the user clicks a contact item, I would like to display a checkmark in front of the item.

For the connection to Meteor DDP I use the awesome library inProgress-team/react-native-meteor.

import Meteor, { connectMeteor, MeteorListView, MeteorComplexListView } from 'react-native-meteor';

class ContactsPicker extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        subscriptionIsReady: false
    };
}

componentWillMount() {
    const handle = db.subscribe("contacts");
    this.setState({
        subscriptionIsReady: handle.ready()
    });
}

render() {
    const {subscriptionIsReady} = this.state;
    return (
        <View style={gs.standardView}>
            {!subscriptionIsReady && <Text>Not ready</Text>}
            <MeteorComplexListView
                elements={()=>{return Meteor.collection('contacts').find()}}
                renderRow={this.renderItem.bind(this)}
            />
        </View>
    );
}

The first problem is, that subscriptionIsReady does not trigger a re-render once it returns true. How can I wait for the subscription to be ready and update the template then?

My second problem is that a click on a list item updates the state and should display a checkmark, but the MeteorListView only re-renders if the dataSource has changed. Is there any way to force a re-render without changing/ updating the dataSource?

EDIT 1 (SOLUTION 1):

Thank you @user1078150 for providing a working solution. Here the complete solution:

'use strict';
import Meteor, { connectMeteor, MeteorListView, MeteorComplexListView } from 'react-native-meteor';


class ContactsPicker extends React.Component {

getMeteorData() {

    const handle = Meteor.subscribe("contacts");
    return {
        subscriptionIsReady: handle.ready()
    };
}

constructor(props) {

    super(props);

    this.state = {
        subscriptionIsReady: false
    };
}

componentWillMount() {
    // NO SUBSCRIPTION HERE
}

renderItem(contact) {
    return (
        <View key={contact._id}>
            <TouchableHighlight onPress={() => this.toggleSelection(contact._id)}>
                <View>
                    {this.state.selectedContacts.indexOf(contact._id) > -1 && <Icon />}
                    <Text>{contact.displayName}</Text>
                </View>
            </TouchableHighlight>
        </View>
    )
}

render() {
    const {subscriptionIsReady} = this.data;
    return (
        <View>
            {!subscriptionIsReady && <Text>Not ready</Text>}
            <MeteorComplexListView
                elements={()=>{return Meteor.collection('contacts').find()}}
                renderRow={this.renderItem.bind(this)}
            />
        </View>
    );
}
}

connectMeteor(ContactsPicker);
export default ContactsPicker;

Solution

  • You have to do something like this :

    getMeteorData() {
        const handle = Meteor.subscribe("contacts");
        return {
            ready: handle.ready()
        };
    }
    render() {
        const { ready } = this.data;
    
    
    }