Im using React with Meteor. In my top level component I have my main subscriptions:
export default withTracker(() => {
let groupsSub = Meteor.subscribe('groups');
let eventsSub = Meteor.subscribe('events');
let userSub = Meteor.subscribe('currentUser');
return {
groups: Groups.find({}).fetch(),
events: Events.find({}).fetch(),
user: Meteor.user() || false,
};
})(App);
The subscription data is passed as props to a child component which is on a new page (using React Router 4).
This is working so far. On the child page I also need to get an ID from the props and use it as part of an additional subscription called CommentsApiSub:
export default withTracker(props => {
const attachedTo = props.group[0]._id;
let CommentsApiSub = Meteor.subscribe('comments', { attachedTo });
return {
comments: CommentsApi.find({}).fetch(),
};
})(Child);
And this is the CommentsApi publication:
Meteor.publish('comments', function({ attachedTo }) {
console.log(attachedTo);
return CommentsApi.find(
{ attachedTo },
{ fields: { date: 1, body: 1, user: 1 } },
);
});
If I navigate to the page it works fine, but if I refresh the page I get an error:
Uncaught TypeError: Cannot read property '_id' of undefined
I know this is because props.group hasnt loaded but im not sure how to delay calling my comments subscription?
You need to check if if Meteor subscription is ready before attempting to load your components. Meteor.subscribe() returns a subscription handle, which contains a reactive data source called ready(). As an example by using your code;
export default withTracker(() => {
const groupsSub = Meteor.subscribe('groups');
// Remaining of the code here
return {
loading: !groupsSub.ready()
groups: Groups.find({}).fetch(),
// Other props
};
})(App);
And in your render() method, you can use that loading prop to check if the subscription ready;
render () {
const { loading } = this.props;
if (loading) {
return (
<h2>Loading Page ...</h2>
);
}
// Remaining of the code
}
You can refer to the official Meteor documentation here.