meteor-publish-composite icon indicating copy to clipboard operation
meteor-publish-composite copied to clipboard

Publication indicates it is ready before all data is published

Open sahanDissanayake opened this issue 9 years ago • 35 comments

Hi @reywood ,

Is there a way to debug why I'm not getting the joined data from the server ?

This is just returning the results

Meteor.publishComposite('jobs', {
    find() {
        return Jobs.find();
    },
    children: [
        {
            find(job) {
                return Properties.find(
                    {
                        _id: job.propertyID
                    },
                    {
                        sort:{createdAt: -1}
                    }
                );
            }
        },
        {
            find(job) {
                return Meteor.users.find(
                    {_id: job.createdBy},
                    {limit: 1}
                );
            }
        }
    ]
});

As this one

Meteor.publish('jobs', {
  return Jobs.find();
});

sahanDissanayake avatar Dec 05 '15 08:12 sahanDissanayake

I;m using react on my project too something similar to this https://github.com/micouz/meteor-react-tutorial-next

sahanDissanayake avatar Dec 05 '15 09:12 sahanDissanayake

This may be caused by publishComposite returning the ready DDP message before the remaining data. I have a similar problem while trying to subscribe on the server with FastRender https://github.com/wekan/wekan/issues/431.

mquandalle avatar Dec 10 '15 04:12 mquandalle

Yep.. This is an issue.. The ready event comes through before the data is fetched.. Any thoughts on a fix @mquandalle ? @reywood ??

getMeteorData() {

        const propertyHandle = Meteor.subscribe('properties');

        const data = {};
        console.log(handle.ready())
        if( propertyHandle.ready()) {

            data.properties = Properties.find().fetch();
        }

        data.currentUser = Meteor.user()

        return data;
    }

Here the propertyHandle.ready() output true even if the subscription is not ready to send the data down.. Because of this I cannot use FastRender, and React SSR too..

sahanDissanayake avatar Dec 10 '15 09:12 sahanDissanayake

@reywood here we go, https://github.com/sahanDissanayake/hello-react-meteor

You could see the difference when you change publishComposite to be normal meteor publish

sahanDissanayake avatar Dec 11 '15 07:12 sahanDissanayake

https://github.com/sahanDissanayake/hello-react-meteor/blob/c19a0dbf4417f43ed533fa14791a4c0974b4bbbc/server/publications.js

sahanDissanayake avatar Dec 11 '15 07:12 sahanDissanayake

Any thoughts on the issue ??

sahanDissanayake avatar Dec 12 '15 06:12 sahanDissanayake

I tried to fix this issue, but it may require a rather large refactoring of the internal implementation. I would love to read @reywood on the matter.

We should take inspiration of Meteor.publish implementation here. Especially it seems that under the hood Meteor use observeChanges instead of `observe to publish the cursor.

mquandalle avatar Dec 12 '15 19:12 mquandalle

@mquandalle @reywood Should I open a new issue for the handle.ready() functionality issue ??

sahanDissanayake avatar Dec 14 '15 03:12 sahanDissanayake

+1

TedAvery avatar Dec 31 '15 05:12 TedAvery

This fix is badly needed or SSR will be impossible with this package. Is there a way I can help?

eXon avatar Jan 03 '16 02:01 eXon

@reywood Do you think there is a fix for this ? Like @eXon mentioned can we help somehow to get this fixed ?

This is a comment found regarding the issue

So yeah, regarding reywood:publish-composite, englue/meteor-publish-composite#67 is an issue for SSR since it currently marks the subscription as ready as soon as the data for the "primary" cursor is sent, and data for the "secondary/joined" cursors get sent after that.

I'm not sure whether it's the only issue though : trying to use the latest meteor-react-router-ssr with reywood:publish-composite, I'm seeing no data at all in the server-side subscription, even on the primary cursor

sahanDissanayake avatar Jan 11 '16 01:01 sahanDissanayake

I'm still fairly new to Meteor, but as a temporary workaround, I believe I achieved what this package helps with by manually chaining together two subscriptions in getMeteorData of my React component.

FormContainer = React.createClass({
  mixins: [ReactMeteorData],
  getMeteorData() {
    var data = {};
    var shortname = this.props.shortname;
    var handle = Meteor.subscribe('form_by_shortname', shortname);
    if (handle.ready()) {
      data.form = Forms.findOne({shortname: shortname});
      var handle2 = Meteor.subscribe('template_by_id', data.form.template);
      if (handle2.ready()) {
        data.form.template = FormTemplates.findOne({ _id: data.form.template });
      }
    }
    return data;
  },
  render() { ... }
}

TedAvery avatar Jan 11 '16 09:01 TedAvery

@TedAvery this is good for simple structures,

But when it comes to this https://docs.mongodb.org/manual/core/data-model-design/#normalized-data-models

We need the publishComposite to work as it is suppose to

sahanDissanayake avatar Jan 11 '16 09:01 sahanDissanayake

@TedAvery the issue with doing that on the client is that it requires more data roundtrips. That's what this package is supposed to avoid :-)

yched avatar Jan 11 '16 09:01 yched

+1

davegariepy avatar Jan 19 '16 03:01 davegariepy

++1

john-osullivan avatar Feb 04 '16 00:02 john-osullivan

+1

tcastelli avatar Mar 10 '16 08:03 tcastelli

+1 Even from a non-SSR perspective, it would be nice (and expected) if a publishComposite didn't respond ready until all children queries are ready.

pcorey avatar Mar 14 '16 15:03 pcorey

+1

lukehollis avatar Jun 25 '16 21:06 lukehollis

+1 Any news on this?

MaxTwentythree avatar Aug 08 '16 11:08 MaxTwentythree

+1

stolinski avatar Aug 20 '16 00:08 stolinski

+1

achapela avatar Sep 08 '16 03:09 achapela

+1

rodcope1 avatar Sep 15 '16 13:09 rodcope1

+1

JWDobken avatar Feb 09 '17 18:02 JWDobken

+1

ghost avatar Mar 06 '17 17:03 ghost

+1

mynameiskyleok avatar Mar 28 '17 17:03 mynameiskyleok

I've tried repeatedly to reproduce this problem, but I can't get it to happen. If anyone can create a GitHub repo that reproduces this problem, I would be very grateful.

reywood avatar May 02 '17 22:05 reywood

We have reproduced this problem with a normal Meteor.publish as well; when publishing the relations of one of our Collections we return an array of cursors in a normal Meteor.publish and when subscribing to this publication subscription.ready() will fire before all data from the relations is actually there.

KoenLav avatar Mar 31 '18 08:03 KoenLav

Also, to add: for us this problem only appears when a previously rendered component also subscribes on a subset of one (or more) of the relations.

For instance: when displaying a paginated list of a collection we subscribed on the 'listWithRelations' composite publication which provided the first x (20) results of the collection together with all the related fields (but only those items which are actually necessary to render the current list, not the entire collection).

Afterwards when we go to the create page we subscribe on the 'relations' publication (normal Meteor publication) which is supposed to load data for all the relations, but (I assume) because we were previously subscribed to only a subset of the same collection we are now subscribing to the subscription returns ready too early (because we were previously subscribed, but to a subset).

We can confirm that the create component ONLY and EXACTLY renders exactly those items which were in the 'subset subscription' and that the problem is resolved when the page is refreshed.

So it appears that Meteor does not properly destroy composite subscriptions on the client side when a component is unmounted and still believes the subscriptions to be available.

I hope this sheds some light for some other people.

The solution we have implemented for now is no longer subscribing on the subset of the relations on our list page, but simply subscribing on entire 'relations' publication right away. While not ideal, it is acceptable for our use-case.

KoenLav avatar Mar 31 '18 09:03 KoenLav

+1

fabyeah avatar Apr 01 '18 00:04 fabyeah