Search code examples
mongodbmeteordelay

Mongo query slow, data shows before query


I have created two templates ( A and B).

A - Shows up when a user has not created documents in a certain Mongo collection.

B - Shows up if the user has created documents in the collection.

Essentially I am displaying a "Theres nothing here message" when no content exists.

To achieve this I use a helper to query mongo to check if documents exist. It looks like the following:

defaultCheck: function() {
  var offerid = this.offerAccepted;

  var id = Meteor.userId();

  var result = Listing.find({
    $or: [{
      creator_id: Meteor.userId(),
      status: "Completed"
    }, {
      offer_creator: Meteor.userId(),
      status: "Completed"
    }]
  });

  return Boolean(result.count());
}

So this returns a true or false Boolean value.

In my layout template I use #if to check the value of the defaultCheck helper and either hide or show the A or B Template

{{#if defaultCheck}}
{{#each meetup}}
{{> ProfileActiveCard}}
{{/each}}
{{else}}
{{> DefaultProfileActive}}
{{/if}}

The Issue is that the query is too slow and the A template briefly shows up (flickers) before the query completes.

How can I prevent this?


Solution

  • Here's my suggested way to show a spinner while data loads:

    Private variables:

    var isDataLoaded = false;
    

    Helpers:

    dataLoaded: function() {
      return isDataLoaded;
    }
    
    defaultCheck: function() {
      var offerid = this.offerAccepted;
    
      var id = Meteor.userId();
    
      var result = Listing.find({
        $or: [{
          creator_id: Meteor.userId(),
          status: "Completed"
        }, {
          offer_creator: Meteor.userId(),
          status: "Completed"
        }];
      });
    
      isDataLoaded = true; // should be set to true only after database query finishes
    
      return Boolean(result.count());
    }
    

    Template:

    {{#if !dataLoaded}}
        {{> spinner}}
    {{else}}
        {{#if defaultCheck}}
            {{#each meetup}}
                {{> ProfileActiveCard}}
            {{/each}}
        {{else}}
            {{> NoDataFoundTemplate}}
        {{/if}}
    {{/if}}
    

    I am not 100% sure this will work as expected or if it's the best way to do it, but it's a start.