Have my publication fetch data from another collection

Hi! I have my Devices collection that have a property called “createdBy” that holds the user ID that created the entry, and I want to display that user name in the frontend instead of the ugly userId string.

My publication is really simple and looks like this.

Meteor.publish('devices.view', function devicesViewPublication(_id) {
  check(_id, String);

  if (this.userId && isAdmin(this.userId)) {
    return Devices.find({ _id });
  }

  return this.ready();
});

How can I achieve that?

Thanks a lot!

bump!

Sorry, I really need help on this topic.

Thanks!

Check this section of the Meteor Guide.

Thank you so much @robfallows!

That solved my issue. My actual code now looks like this and works! I’ll publish here so others may benefit.

meteor add reywood:publish-composite

In my publication

...
import { publishComposite } from 'meteor/reywood:publish-composite';
...
...
publishComposite('devices.view', function devicesViewPublication(deviceId) {
  check(deviceId, String);

  if (this.userId && isAdmin(this.userId)) {
    return {
      find() {
        return Devices.find({ _id: deviceId });
      },
      children: [
        {
          find(device) {
            return Meteor.users.find(
              { _id: device.createdBy },
              {
                fields: {
                  name: 1,
                  avatar: 1,
                  emails: 1,
                  services: 1,
                },
              });
          },
        },
      ],
    };
  }

  return this.ready();
});
...

In my React frontend

...
export default createContainer(({ match }) => {
  const deviceId = match.params._id;
  const subscription = Meteor.subscribe('devices.view', deviceId);

  if (subscription.ready()) {
    const device = Devices.findOne(deviceId);
    const user = Meteor.users.findOne(device.createdBy);

    return {
      ready: true,
      device,
      user,
    };
  }

  return {
    ready: false,
    device: null,
    user: null,
  };
}, ViewDevice);
...
2 Likes