How do you deal with client side subscription management in conjunction with meteor server side rendering?

#1

Server side rendering works fine generally, but when I have pages where I’m subscribing to Mongo data and that file is run on server side, I get errors about Meteor not being defined on server side.

For example:

    export default withTracker(() => {
        let user;
        const getUser = Meteor.subscribe("users");
        const userReady = getUser.ready();

        if(userReady) {
            user = Meteor.users.find().fetch()[0];
        }
    
        return {
            loading: !userReady ? true : false,
            admin: user !== undefined && user.profile.admin ? true : false,
            user: user
        }
      
    })(AdminWrapper);

This code runs fine on client, but when I turn on server side rendering, I get an error that Meteor is not defined on server side and my app crashes. Therefore, content for the resulting pages cannot be rendered via server side. Only React code that doesn’t depend on DB data is rendered. The thing that I do now is have a separate React router file for server and client, but that defeats the purpose of SSR, since half my website can’t render code that depends on the DB.

Is there any way to get this to work correctly and render the data appropriately? Thanks in advance.

#2

Bump for exposure. If anyone solved this problem before, pls respond.

#3

Hi,
From what I understand (don’t know if thats a SSR feature), in regular Meteor you can execute user = Meteor.users.find().fetch()[0]; with no outer if, removing this line and the respective curly braces:

It would just render the component again then the subscription is ready.

Cheers!

#4

Other types of data are problematic too - like Meteor.userId() - how do we handle that?

#5

This is how I deal with it:

  let testSub;
  if (Meteor.isClient) {
    testSub = Meteor.subscribe('tests.all', {});
  }
  if (Meteor.isServer || (testSub && testSub.ready())) {
    data = Tests.find({}, { sort: { createdAt: -1 } }).fetch();
  }
2 Likes