Search code examples
javascriptmeteormeteor-blazemeteor-autoform

Blaze template iterate over object


I am trying to iterate over an object in blaze template (meteor) , in console I can see the data but nothing on template.How can I get this working ? #each not working , arrayify also didn't work.


Added here from comments:

{{#each contactList}} 
 <tr class="clickable" name="edit-contact" >
   <td>{{name}} </td>
   <td>{{email}} </td>
   <td>{{title}}</td>
   <td>{{phone1}}</td>
   <td>{{phone2}}</td>
   <td>{{phone3}}</td>
 </tr>
{{/each}}

JS:

contactList: function() { 
  $.ajax({ 
    url: Meteor.absoluteUrl()+'contacts/get_by_company/'+Session.get(‌​'company_id'),
    type: 'GET',
    error: function() { callback(); }, 
    success: function(res) { console.log(res); return res; }, 
  });
}

Solution

  • The immediate reason for your contactList helper not providing you with your expected list of contacts is that you call an asynchronous function ($.ajax) and do not return anything after that call.

    See How do I return the response from an asynchronous call?

    Meteor is not aware of when your asynchronous call completes, nor of its result.

    If you really need to keep your AJAX call, you could store the result in a ReactiveVar and read it in your helper. Meteor knows that it should automatically re-run your helper whenever a reactive source is updated within that helper function. Therefore, your template will automatically receive the result when it arrives.

    import { ReactiveVar } from 'meteor/reactive-var'
    
    var contacts = new ReactiveVar();
    
    Template.templateName.onCreated(function () {
        $.ajax({ 
            url: Meteor.absoluteUrl()+'contacts/get_by_company/'+Session.get(‌​'company_id'),
            type: 'GET',
            error: function() { callback(); }, 
            success: function (res) {
                console.log(res);
                contacts.set(res); // Update the reactive var.
                return res; // Useless.
            }
        });
    });
    
    Template.templateName.helpers({
        contactList: function () {
            return contacts.get(); // Will get updated later on and Meteor will automatically refresh the helper.
        }
    });
    

    That being said, within Meteor there is hardly a need for REST endpoints, as pointed out by @jordanwillis. If you can re-factor the way you retrieve your contacts list, you can get a much more Meteor-like structure, with all its advantages (real time update, flexibility of manipulating the data client-side, etc.)