[SOLVED] - How can I make sure if documents are subscribed?

Some case I’m able to get documents back but some case I’m not. and I don’t know why this is happening.

  const {_id} = card;

  const query = {cardId: _id, commentId: {$exists: true}};
  console.log(`query:`, query);
  
  const activities = Activities.find(query).fetch();
  console.log(`activities:`, activities);

Wether I get documents back or not, I successfully get _id from card which means query always has value.

Also when I look at activities database on studio 3t, I query with cardId: _id and I see documents existing there.

What could be the reason why I don’t get documents back some cases?

Attempts

I tired a multiple ways of fetching documents

1, Same result above like some case I got documents back but some times not.

const activities = Activities.findOne(query);

2, same as 1

const activities = Activities.findOne({cardId: _id});

3, same as 1

const activities = Activities.findOne(query);

4, got an error saying
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

  const activities = useFind(() => Activities.find(query), [query]);

I also checked if activities are subscribed with meteor extension.
And yes I see documents with cardId: _id existing on activities database in Minimongo tab.

My suggestions:

  1. const { _id } = card || {}. It is better to cover for situations where card is undefined.
  2. Have a DB index for cardId.
  3. Restrict de returned fields to only the document _id an see if you get all documents in this case.
  4. Run all these on the server side where you only have a server - DB relationship. Would be interesting to see if you get the full result on the server but not on the client.
1 Like

How about commentId? It might be missing in some of the docs

1 Like

What if you change it to:

const activities = useFind(() => _id ? Activities.find(query) : null, [_id]);
2 Likes

I am really new to meteor so your suggestions 2 and 3, could you talk a little more about these? or could you provide an example code?

2 Likes

What I see in db, I’m pretty sure that all of the documents have commentId

But I also removed commentId: {$exists: true} inside query and tried to fetch documents and the result was the same, I got documents back in some case but not all the time.

I tired your suggestion and I didn’t get any documents for all cases.

I was wrong, It should be

const activities = useFind(() => _id ? Activities.find(query) : null, [_id]);

If you still couldn’t get any documents, check for your subscription.

2 Likes

You are awesome! Now I’m getting documents all the time! Thanks a lot!

Could you also explain why this works?

I don’t know why my original code caused Maximum update depth exceeded.

const activities = useFind(() => Activities.find(query), [query]);

I understood you added the condition that checks if _id exist, but why the dependency array? needs to be _id ?

I can’t see your whole component code but it looks like your query depends on _id variable only, so just put it in dependency array.

1 Like

I guess the query Activities.find(query) returned undefined. An undefined variable in dependency/component state can cause the that issue.

1 Like

Awesome! Thank you @minhna !

For 2. you have a full explanation here: http://sparkbyspark.com/james-fortier-spark-creative-portfolio-samples/case-studies/project-ricochet-meteor-framework-how-to.pdf Check fro issue 8. This is one of the main causes for people returning to this forum with “too slow” issues. It will not affect you now or in the process of learning Meteor but in production, this is a must.
Documentation on how to create indexes: Collections | Meteor API Docs

Some code exemple:

import { Meteor } from 'meteor/meteor'
import { Activity } from './activitySchema' // this is your DB schema

const uri = Meteor.isProduction ? process.env.MONGO_ACTIVITIES_URL : 'mongodb://127.0.0.1:3001/meteor' // in production you might use multiple DBs (different db URIs). It defaults to your MONGO_URL
const _driver = new MongoInternals.RemoteCollectionDriver(uri, {})

const Activities = new Meteor.Collection('activities', { _driver })

Activities.attachSchema(Activity)
Activities.createIndexAsync({ type: 1, name: 1 }) // you just created (or attached to an existing collection) and declare (create) your indexes.

Activities.deny({
  insert: () => true,
  update: () => true,
  remove: () => true
})

export default Activities

A DB schema may look like this:

// the './activitySchema' file from the import above.
import SimpleSchema from 'simpl-schema'

const Activity = new SimpleSchema({
  name: String,
  description: { type: String, optional: true },
 // .....
})
export { Activity }

Simply put, whatever you query for in a Mongo Collection must be covered by an index or many. You may read here about compound indexes which are what you are going to use more as your DB schema gets more complex and you do more complex queries: https://www.mongodb.com/docs/manual/core/index-compound/

  1. Fields: Collections | Meteor API Docs
1 Like

Thank you for all links and examples!