Meteor find each item in Mongo DB


#1

I have Collection like this:
Category = new Mongo.Collection(‘categories’);

let categories = [
{
name: ‘ENGLISH’,
sub_categories: [
‘Listening’, ‘Speaking’, ‘Writting’,‘Reading’,‘Toeic’
]
},
{
name: ‘SoftSkill’,
sub_categories: [
‘CV and CL’, ‘Presentation’, ‘Teamwork’
]
}

So now I want to display in meteor, I use
{{#each categories}}

{{this}}" {{/each}}

But in my submit.js file I use js:
Template.postSubmit.helpers({
categories: () => {
return Category.find({name: this name});
}
});
IT can’t work. I’m a beginner, so can you help me to see my mistake and fix it,
Thanks a lot


#2

Your main issue is that you haven’t actually put any data into your Category collection. If you still have the insecure and autopublish packages (installed by default) you can do this in the client:

In lib/Category:

Category = new Mongo.Collection('categories');
// Do some setup:
// Iterate over an array of categories and insert into collection
[
  {
    name: 'ENGLISH',
    sub_categories: [
      'Listening', 'Speaking', 'Writing','Reading','Toeic'
    ]
  },
  {
    name: 'SoftSkill',
    sub_categories: [
      'CV and CL', 'Presentation', 'Teamwork'
    ]
  }
].forEach(category => {
  // This bit does the inserts
  Categories.insert(category);
});

Then in your submit.js:

Template.postSubmit.helpers({
  categories() => {
    return Category.find({name: this name});
  }
});

And your template:

<template name="postSubmit">
  {{#each categories}}
    <div>{{name}}</div>
    {{sub_categories}}
  {{/each}}
</template>

That should work - but it’s not the right way to do it. I recommend taking a look at the basic Meteor Blaze tutorial and the Meteor Guide to get a solid grounding in best practices :slight_smile:.


#3

Sorry but it can’t work. This is my code:
server/publish.js:
Meteor.publish(‘categories’, () =>{
return Category.find().fetch();
})
in client/mainjs:
Meteor.subscribe(‘categories’);
After that in lib/categories I create:

Category = new Mongo.Collection(‘categories’);

let categories = [
{
name: ‘IT’,
sub_categories: [
“Java”,
“PHP”,
".NET",
“Android/iOS”,
“HTML/CSS”,
“Java script and Framworks”,
“Ruby on Rail”
]
},
{
name: ‘ENGLISH’,
sub_categories: [
‘Listening’, ‘Speaking’, ‘Writting’,‘Reading’,‘Toeic’
]
},
{
name: ‘SoftSkill’,
sub_categories: [
‘CV and CL’, ‘Presentation’, ‘Teamwork’
]
},
{
name: ‘ENTERTAISMENT’,
sub_categories:[
‘Sports’, ‘Games’, ‘Music & Videos’, ‘Fashion’,‘Talk show’
]
}
];
categories.forEach( (el, i) => {
let sameCategories = Category.find({name: el.name}).count();
if (sameCategories === 0){
Category.insert(el);
}
});

client/postSubmit.js
Template.postSubmit.helpers({
categories: () => {
return Category.find({name: this.name});
},
subCategory: ()=>{
return Meteor.settings.public.subCategory;
}
});

then in submit.html i use
select name=“categoryMain” class=“form-control”>
{{#each categories}}
{{this}}"
{{/each}}
/select>

p/s: Sorry again because I don’t know where to format code in here :slight_smile:


#4

Paste your code between triple backticks like this:

```
paste your
code here
```

Okay, let’s try and fix this step-by-step.

  1. Database fixtures.

The usual way to set up your collection with some predefined content is in the server’s Meteor.startup().

In server/main.js

Meteor.startup(() => {
  if (Category.find().count() === 0) {
    [
      {
        name: 'IT',
        sub_categories: [
          'Java',
          'PHP',
          '.NET',
          'Android/iOS',
          'HTML/CSS',
          'Java script and Framworks',
          'Ruby on Rail',
        ],
      },
      {
        name: 'ENGLISH',
        sub_categories: [
          'Listening', 'Speaking', 'Writting', 'Reading', 'Toeic',
        ],
      },
      {
        name: 'SoftSkill',
        sub_categories: [
          'CV and CL', 'Presentation', 'Teamwork',
        ],
      },
      {
        name: 'ENTERTAISMENT',
        sub_categories: [
          'Sports', 'Games', 'Music & Videos', 'Fashion', 'Talk show',
        ],
      },
    ].forEach(doc => {
      Category.insert(doc);
    });
  }
});
  1. Publish your data

In server/publish.js:

Meteor.publish('categories', function() { // Don't use () => { here or you will lose the context.
  return Category.find(); // Do not use fetch() - in a publish you need to return a cursor, not an array
});
  1. Subscribe to your publication

In client/postSubmit.js:

Template.postSubmit.onCreated(function() { // Don't use () => { here or you will lose the context.
  // You should be using a template subscription.
  // If you use a global (Meteor.subscribe) you will also have to deal with stopping this subscription when you've finished with it.
  this.subscribe('categories');
});
  1. Set up your template helpers

In client/postSubmit.js:

Template.postSubmit.helpers({
  categories() => {
    return Category.find({ name: this.name });
  },
  subCategory() => {
    return Meteor.settings.public.subCategory;
  },
});
  1. Check your template

I’m unclear what you’re trying to achieve here, but {{this}}" looks wrong.


#5

I want to pour data into select, then I have 4 option: IT, Soft Skills, English and Entertaisment. When I choose 1 in 4 option I can do something with this option.Detail: When I choose IT in below will display each sub category of IT. And {{this}} to choose right option I just click.


#6

Quick and dirty repo here: https://github.com/robfallows/vomadien95

No apologies for the hasty coding and poor structure.


#7

Thanks you very much. It’s clearly and necessary for me. I will improve my skill to better. :slight_smile:


#8

Can you help me one more.

I saved categories and sub_category for each post of my blog. So now I want to display posts by categories that I have choose. For example:

Posts.find({"name": "IT"})

or

Posts.find({"sub_categories": "Java"})

But it very handicraft. How I can choose the posts by categories automation. It mean that, I show each sub categories and choose one then app can return all article of this categories.

Thanks a lot


#9

You would probably do this most easily using Meteor’s pub/sub and reactively re-subscribe according to the user’s selection. Check the Meteor Guide on publications and data loading.

To reactively re-subscribe on a route change: https://guide.meteor.com/data-loading.html#changing-arguments - although you could use any reactive data source to manage this (ReactiveVar, ReactiveDict, etc).

Or, you could do the (re)subscription in the event handler if that’s simpler for this use case.

Alternatively, you could form the query dynamically to pass to the publish method, but you will need to handle validation very carefully to prevent attack vectors on the publication.

In any event, if you must pass parameters from a subscription to a publication, it’s always better to use keywords than query strings.