Empty List from Collection - withTRacker

I’m trying to display the contents of a Collection, but I keep getting an empty list.
I’ve been using the Todos app as a template but I just can’t get it to retrieve data from the Collection. Here is what I have so far.

publications.js

import { Meteor } from 'meteor/meteor';

import Children from '../children.js';

Meteor.publish('children.public', function childrenPublic() {
  return Children.find({
    userId: { $exists: false },
  }, {
    fields: Children.publicFields,
  });
});

children.js

import { Mongo } from 'meteor/mongo';

const Children = new Mongo.Collection('Children');

Children.publicFields = {
  name: 0,
  dateOfBirth: 0,
  address: 0,
  sponsor: 0,
  situation: 0,
};

export default Children;

ChildrenPageContainer.jsx

import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';

import Children from '../../api/children/children.js';
import ChildrenPage from '../pages/Child/ChildrenPage.jsx';

const ChildrenPageContainer = withTracker(() => {
  const publicHandle = Meteor.subscribe('children.public');

  return {
    user: Meteor.user(),
    loading: !publicHandle.ready(),
    connected: Meteor.status().connected,
    children: Children.find({
      $or: [
        { userId: { $exists: false } },
      ],
    }).fetch(),
  };
})(ChildrenPage);

export default ChildrenPageContainer;

And the ChildrenPage is basically MaterialUI Sorting and Selecting table: https://material-ui.com/components/tables/

The ChildrenPageContainer is supplied to the Route component like this:

<Route path="/child/list" component={ChildrenPageContainer} />

And I keep getting a warning in the browser console:

Warning: Failed prop type: Invalid prop `component` of type `object` supplied to `Route`, expected `function`.
    in Route (created by MainLayout)
    in MainLayout
    in ThemeProvider modules.js:3537:15

I have a feeling that the component does not rerender as the data arrive, and that this warning might have something to do with it. Either way, I am out of ideas, and would be very thankful if someone could point out the problem.

Have you tried:

component={()=> <ChildrenPageContainer/>}

in the Route ?
It seems that this is the expected prop and the PropType check is the one stopping the render…

I suggest using mongol or similar to check what data is available on the client. If the data is not visible, then you know the issue is in your publication, otherwise it is on the React side of things and we can work from there.

1 Like

Hi andreyg. I’ve just tried it, and the problem persists. But at least the warning is gone :slight_smile:. Thanks!

Hi hemalr87. I installed the mongol plugin, at it seems that there is something wrong with the publication. I will double-check the code, but I’m pretty sure I copy-pasted properly :slight_smile:. Do you maybe have any further hints?
Thank you for your interest!

Baby steps dude…

  • By the way, after a second pass on the code you posted, why are you using $or operator in the container?
    As I see it you can just write:
    children: Children.find({ userId: { $exists: false } }).fetch(),
  • Secondly, can you check the publicFields property? console.log it and see that you get the correct parameters, this way you know the publication is accessed on the server.

  • Third, did you import the publications.js file on the server? Usually, when I have publications that seem non-existent it’s because I forgot to add the import line on the server startup files.

  • And finally, fourth: try to run the query on the mongo database and see if you get anything, maybe the publication works as intended, but you just don’t have any objects in the database that answer the query.

1 Like

Hi andreyg. As you correctly suggested in the third point, I forgot to import the publication.js. It’s working now as intended! Thank you for your help!

P.S. I also removed the $or operator. It was a copy/paste thing, and I thought I might need it later, but I can also always add it later.

1 Like

Well, the way it works is the server needs access to the collection code you wrote and also the publication code. When the server imports them, (anywhere in the project mind you, in this case the fixtures.js file… ) it constructs the publication. Creating a listener for it that you can later subscribe to from the client. And this way access the data.
This is the core of the meteor framework, all you have to do is write the publication function and define the collection schema in two files and make sure they are imported at some point during startup on the server side.

e.g [import “…/imports/api/todos/server/publications.js”]. Later, you can subscribe to it using the container component on the client and get the data published by the publication.

Good luck!

Thanks for the clarification on the fixtures.js. I edited it out once I realized it was the missing import…