Meteor reactive: false returns empty cursor [SOLVED]

I’m trying to remove reactivity from cursor:

return Food.find({},{reactive: false}).fetch().map(food => {
   return food;
});

but this is always empty. Only when I remove {reacitve: false} or change it to true I get data.

Am I doing something wrong?

Cheers

This is due to data not being available when this code runs. With normal reactivity, when the data became avalable, this would rerun and you would get a have a cursor bearing data. The solution here would be to use the reactivity of a subcriptions ready() function to cause this code to execute once the data is available to the client.

I put this in my publish function:

const food = Food.find(selector, options);
 if(food.count()) {
   return results;
} else {
   this.ready();
}

but I always get data there, so the count is never null/empty, just on the client side.

Even leaving this.ready() returns an empty cursor always

You will always have data available on the server. The client however doesn’t have the data until it is transferred over a connection with varying speed and latency. this.ready() in the publish function won’t help here. You need to use the ready() function attached to the subscription handle that is returned from Meteor.subscribe. If you are using Blaze you can use template level subscriptions and the built in Template.subscriptionsReady to wait to render part of your template till data is available.

{{#if Template.subscriptionsReady}}
    data dependent parts here
{{/if}}

If you are using react with createContainer then you can do something like this.

const myComponent = ( { ready, data } ) => (
    <div>
        { ready &&
            <p>{data.someProperty}</p>
        }
    </div>
));

const myComponentContainer = createContainer(( params ) => {
    const ready = Meteor.subscribe("somePublicationName").ready()
    const data = Collection.findOne();
    return {
        ready,
        data,
    }
};

I’m using angular-meteor but it’s similar to React as I can see.

I copied your solution for React but still not working:

var ready = this.subscribe('food', () => [{
            limit: parseInt(this.getReactively('perPage')),
            //skip: parseInt((this.getReactively('page') - 1) * this.perPage),
            sort: this.getReactively('sort')
        }, this.getReactively('filters'), this.getReactively('searchText'), this.getReactively('user.following')
        ]).ready();

And on helpers:

food() {
                const food = Food.find({},{reactive:false}).fetch();
                console.log(food); // still empty as do the scope on html
                return {
                    ready,
                    food
                };
}

I know absolutely nothing about angular so I can’t say how this would be implemented but the jist of it is that since your fetch() is not reactive, ready() needs to run within the context of a Tracker computation so that that when it’s value changes it can invalidate the current computation and cause the function to rerun. With React, createContainer creates the needed context. Angular must have similar.

I tried to google something similar to angular-meteor this time and I found this solution:

I’ve never seen a find() inside of subscribe function before, but anyway, works like a charm.

Thanks!