2

I have made a recipe app. I am listing all the recipes from the database. I want to add a feature that filters the recipes, to only show the user's recipes.

I have published the recipe collection and subscribed to it in a different file. It loads all the recipes just fine. But when I click to only show the user recipes, no recipes show and I get an error message saying "You are on client so you must either provide a callback to get the data or subscribe first"

I am confused because I thought I was subscribed to the collection since it populates all the recipes. Yet when I try to filter the data I am told I need to subscribe.

My publication looks like this and this is the path.

imports/api/recipes.js

if (Meteor.isServer) {
    // This code only runs on the server
  Meteor.publish('recipes', function recipesPublication() {
    return Recipes.find({
    });
  });
}

I have a body.js file that imports that file and subscribes to the data. It displays all the recipes so I assume it is subscribing to the Recipe collection. The if statement handles which recipes should display. If it is false it shows all recipes and that works fine. If it is true it will only show the recipes that belong to the user. This is where I get the error message. The odd part that confuses me is the commented out Mongo query command will filter the data. So how come I am told I need to subscribe to the data when using Grapher?

Template.body.onCreated(function bodyOnCreated() {
    this.state = new ReactiveDict();
    Meteor.subscribe('recipes');
    Meteor.subscribe('ingredients');
  });

Template.body.helpers({
  recipes() {
      const instance = Template.instance();
      if (instance.state.get('showMyRecipes')) {
        // return Recipes.find({ owner: Meteor.userId() }, { sort: { createdAt: -1 } });
        const query = Recipes.createQuery({
          $filters: {
               owner: Meteor.userId(),
           },
           name: 1,
           instructions: 1,
        });
        return query.fetch();
      }
      return Recipes.find({}, { sort: { createdAt: -1 } });
    },
    ingredients() {
          return Ingredients.find({});
        },
});
Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
Q-Win
  • 31
  • 3
  • 1
    what is createQuery? Is that graphql? It's not a method of a meteor collection (https://docs.meteor.com/api/collections.html). Could it be that you are confusing the two? graphql vs. meteor collections. The commented-out code looks correct. Did that not work? – Christian Fritz Jul 31 '20 at 03:11
  • The commented out code does work. createQuery is part of the Grapher (https://cult-of-coders.github.io/grapher/#Introduction) package. Grapher is supposed to make for faster queries and set up relations. – Q-Win Jul 31 '20 at 16:34
  • ah, I see. Thanks for adding that to the title. I've also created a tag for it. – Christian Fritz Aug 01 '20 at 00:48
  • Is it possible that this code (which produces the confusing error) runs before the subscription is `ready()`? – Christian Fritz Aug 01 '20 at 00:51
  • Yes that is possible. Is there a way to check or wait until the subscription is ready? Also the commented out code works. Does it matter that Im using the Grapher package vs a Mongo query? – Q-Win Aug 03 '20 at 14:06
  • yes, you can: `sub = Meteor.subscribe('recipes');` and then `if (sub.ready()) { ... }`. – Christian Fritz Aug 03 '20 at 15:12

0 Answers0