0

I published data on the server side, but when I subscribe the data, I first got empty and then real data. How can I subscribe the real data at first?

class BlogItem extends Component{
  render(){
      console.log(this.props.posts);
      return(
        this.props.posts.map(post =>{
          return(
            <li className="list-group-item" key={post._id}>
              title:{post.title}
            </li>
          );
        })
      );
  };
}


export default createContainer((props) => {
  Meteor.subscribe('posts');
  return { posts: Posts.find({}).fetch() };
}, BlogItem);

publish on server:

Meteor.startup(() => {
  Meteor.publish('posts', function() {
   return Posts.find({});
 });
});
Han
  • 117
  • 1
  • 9
  • How do you publish it on server side – Shubham Khatri Jun 01 '17 at 05:56
  • Updated question. Thanks! – Han Jun 01 '17 at 06:10
  • Maybe it's trying to return something before the subscription is ready? I don't know much about how to use ```subscriptionReady()``` in react, but try giving [this](https://forums.meteor.com/t/react-component-mount-wait-for-subscriptions-ready/13646/2) a read. – blueren Jun 01 '17 at 06:15
  • Check this https://stackoverflow.com/questions/28890672/meteor-collection-fetch-returns-empty-array-but-is-subscribed – Shubham Khatri Jun 01 '17 at 06:16
  • Fixed, just ignore the empty array and it is gonna re-render when real data comes. – Han Jun 01 '17 at 06:44
  • This might help - https://stackoverflow.com/questions/29153538/meteor-spacebars-if-somecondition-shows-data-briefly-on-page-refresh/29155408#29155408 – sdooo Jun 01 '17 at 13:14

2 Answers2

0

There is no way to make the data get to the client faster. That is how a subscription works. To deal with it, use the subscription handle to test if it is ready and show a loader in the meantime.

class BlogItem extends Component {
  render() {
    const {ready, posts} = this.props;
    if (!ready) return (<div>loading...</div>);
    return (
      <ul>
        posts.map(post => (
          <li className="list-group-item" key={post._id}>
            title:{post.title}
          </li>
        ));
      </ul>
    );
  }
}

export default createContainer(() => {
  const handle = Meteor.subscribe('posts');
  return {
      ready: handle.ready(),
      posts: Posts.find({}).fetch(),
  };
}, BlogItem);
tomsp
  • 1,797
  • 14
  • 17
  • Fixed, just ignored the empty array and it is gonna re-render when real data comes. – Han Jun 01 '17 at 06:49
  • You can do that, but imagine you have 25 different return values from your container. Testing each and every one of them whether they are emptz or `undefined` would be very tedious. So use the `subscription-handle`, that is what it's for. – tomsp Jun 01 '17 at 06:52
0

You need to wait for subscription to complete.

Initially you're getting empty data because your data is not ready.

Wait till your data is ready then pass data, meanwhile show loading page

export default createContainer((props) => {
  const handle = Meteor.subscribe('posts');
  if (handle.ready()) {
   return { posts: Posts.find({}).fetch() };
  } else {
    return { loadingData: true, posts: [] }
 }
}, BlogItem);
Sasikanth
  • 3,045
  • 1
  • 22
  • 45
  • Fixed, just ignored the empty array and it is gonna re-render when real data comes. – Han Jun 01 '17 at 06:49