FlowRouter wait for data before rendering

#1

I have a page that prints some static text and lists items (including links to other parts of my site) from a database. The code looks something like this:

class Example extends Component {

    render() {

        const {items} = this.props;

        return <div className="centeredPage">
            <div className="content">
                <p>This is some static text.</p>
                
                {items.map(item=> {
                    return <Link 
                        url={ item.url } 
                        key={ item._id }
                    >{item.name}</Link>
                })}

            </div>
        </div>
    }
}

export default withTracker(() => {
    Meteor.subscribe('items');

    return {
        items: Items.find().fetch(),
    }
})(Example);

Currently I use a withTracker to load the data from the database. The problem is that when the page initially loads, only the static text is visible, then the items are rendered when the data arrives. The problem here is that google only seem to index the static text and not follow the links to the rest of my site.

What I’m looking to do is to postpone the rendering of page until all the data is present. I’m currently using FlowRouter but looking at their docs it seems like they prefer Component level subscriptions, so if possible, I’m looking for such a solution.

Ps. I’ve looked at the documentation for FlowRouter, but a lot of it references the old.kadira.io and meteorhacks, which both seem to be down right now.

Ps2 the actual component uses some code that’s available on the client only (google maps), so server side rendering is not an ideal solution.

#2

As a solution to this problem you can do the following

export default withTracker(() => {
    const subscription = Meteor.subscribe('items');

    return {
        loading: !subscription.ready()
        items: Items.find().fetch(),
    }
})(Example);

and inside of your render method, you can do the following

 render() {

        const { items, loading } = this.props;

        return !loading ? (
                 <div>
                     <p> Static content </p>
                     {items.map(item => (
                      <Link
                        url={item.url}
                        key={item.key}
                       >
                        {item.name}
                        </Link>)}
                  </div>
              )  : null
    }
}

So until items array is ready (that means subscription is done and all the data is fetched) nothing will be rendered.

However, for the following problem

I think you also need to implement server side rendering

#3

Will look into server side rendering, thanks for the advice :slight_smile: