0
votes

I'm starting to use meteor for a project, and there are several concepts that are being pretty hard to me coming from angular+php.

I'm trying to handle two helpers, for displaying a list of records in a table, based in a date range that I'm storing on a session variable. My template then looks like this, I'm using a helper called noRecords and another called records, records store the actual document set, and in noRecords I'm trying to store as a boolean whether the record document set is empty or not.

    div(class='col-md-8 col-md-offset-2')
        if noRecords
            p There are no records for the selected date 
        else
            table(class='table table-bordered')
                thead
                    tr  
                        td Id
                        td Name

                tbody
                    each records
                        +record

Unfortunately I've not being able to set records and noRecords at the same time without repeating the query, in my javascript code those helpers are now defined like this:

records : function(){
    var startDate = Session.get('searchDate').setHours(0,0,0,0);
    var endDate = Session.get('searchDate').setHours(23,59,59,999);
    var matches = Records.find(
                    {date : { 
                                $gte : new Date(startDate),
                                $lte : new Date(endDate)
                            }
                    });
    return records;
},

noRecords : function(){
    var startDate = Session.get('searchDate').setHours(0,0,0,0);
    var endDate = Session.get('searchDate').setHours(23,59,59,999);
    var matches = Records.find(
                    {date : { 
                                $gte : new Date(startDate),
                                $lte : new Date(endDate)
                            }
                    });
    return records.count() === 0;
}

The date session variable is set by an event.

I guess there must be a better way of doing this instead of executing the query twice, I've tried using reactive variables but I had no luck, since I can't make the reactive variable to update when the minimongo query executes.

Is there any way of achieving this without running two queries?

2
Er, function getValues() { return /*whatever array of values you want */}? Asking for a "cleanest way" is off-topic as it is opinion-based though (you may want to rephrase that), but the usual solution to reduce code duplication is to wrap it in a function. - Kyll
Thanks for the answer, I've edited my question but my worries are more about executing the query twice more than writing it twice, wrapping it in a function still makes it to execute twice. Sorry if it was not very clear. - namelivia
You can use with to get the records and if their count is positive, iterate. Otherwise, show the no records paragraph. I have answered a similar (albeit simpler) question here. - MasterAM

2 Answers

2
votes

If you are repeating the same logic in multiple helpers one solution is to reduce them to a single helper and return an object from it, e.g.:

records : function(){
    var startDate = Session.get('searchDate').setHours(0,0,0,0);
    var endDate = Session.get('searchDate').setHours(23,59,59,999);
    var cursor = Records.find(
                    {date : { 
                                $gte : new Date(startDate),
                                $lte : new Date(endDate)
                            }
                    });
    return {
      cursor: cursor,
      empty: cursor.count() === 0,
      one: cursor.count() === 1
    }
}

And in your template:

if records.one
  p Found One!

Silly example but it can be used more broadly.

Note that in your example you wouldn't actually need the noRecords helper because your template can check for an empty cursor:

each records
  p date
else
  p No records!
0
votes

If you were using Blaze, you could use the {{#each records}}...{{else}}...{{/each}} using your records helper only like this.

<template name="myTemplate">
  <div class='col-md-8 col-md-offset-2'>

  {{#each records}}{{> showRecord}}

  {{else}}<p>There are no records for the selected date</p>

  {{/each}}

  </div>
</template>

You could also use {{#if records}}...{{else}}...{{/if}} since each will iterate over each item in the records cursor

<template name="myTemplate">
  <div class='col-md-8 col-md-offset-2'>

  {{#if records}}

     <table class='table table-bordered'>

     <thead>
       <tr>  
           <td>Id</td>
           <td>Name</td>
        </tr>
      </thead>

      <tbody>
      {{#each}}{{> showRecord}}{{/each}}
      </tbody>

      </table>

  {{else}}<p>There are no records for the selected date</p>

  {{/with}}

  </div>
</template>