dennismonsewicz
dennismonsewicz

Reputation: 25542

MeteorJS: Load spinner while API results are returned

I have an app that is consuming an XML data source.

A user can select a category from a dropdown and an API call is made to pull back an XML data-source for processing. A) How do I update my front-end collection with the data? B) How do I show a spinner while the collection is updated?

JavaScript

var getJobsByIndustry = function(onet) {
  if(typeof(onet) === "undefined")
      alert("Must include an Onet code");

  var url = "onet=" + onet;

  Meteor.call('retrieveJobs', url, function(error, results){
    console.log(results)
  });
};

Template.selector.events({
  'click div.select-block ul.dropdown-menu li': function(e) {
    var selectedIndex = $(e.currentTarget).attr("rel");
    var val = $('select#industryPicker option:eq(' + selectedIndex + ')').attr('value');
    var oldVal = Session.get('currentIndustryOnet');

    if(val != oldVal) {
      Session.set('currentIndustryOnet', val);
      Session.set('jobsLoaded', false);
      getJobsByIndustry(val);
    }
  }
});

Template:

<template name="list">
  <div class="col-md-12">
    {{#if jobsLoaded}}
      <ul class="list-group" id="jobs">
        {{#each jobs}}
          <li>
            <span class="pull-right">{{address}}</span>
            <span id="jobTitle">{{title}}</span>
            <span id="company">{{company}}</span>
            <span id="date"><em>{{dateacquired}}</em></span>
          </li>
        {{/each}}
      </ul>
    {{else}}
      {{> spinner}}
    {{/if}}
  </div>

  <div class="row">
    <div class="col-md-12">
      <div class="row">
        <div class="col-md-2">
          <select id="perPage" class="selectpicker select-block" _val="{{selected_opt}}">
            <option value="10">10 Per Page</option>
            <option value="25">25 Per Page</option>
            <option value="50">50 Per Page</option>
            <option value="100">100 Per Page</option>
          </select>
        </div>

        <div class="col-md-10">
          {{{pagination}}}
        </div>
      </div>
    </div>
  </div>
</template>

Upvotes: 0

Views: 1562

Answers (1)

Andrew Mao
Andrew Mao

Reputation: 36900

It would be great if you could move your backend to Mongo, instead of processing the XML asynchronously yourself. However, you can accomplish this in the following steps:

  • When you make the API call, set a reactive variable (such as a value in Session) to some value to indicate that it is being loaded.
  • When the API call returns, process the data and insert it into a collection (clearing out anything that was previously there, if it is being reused).
  • Set this variable again to indicate that is loaded.

This use case aligns very well with Meteor.subscribe, but you'll have to make your own analogies. To display the spinner, just use the reactive variable in a template:

<template name="userList">
    <div class="well well-skinny user-list scroll-vertical">
        {{#if loaded}}
            Users:
            {{#each users}}
            {{> userPill}}
            {{/each}}
        {{else}}
            {{> spinner}}
        {{/if}}
    </div>
</template>

Where loaded is defined as

Template.userList.loaded = -> Session.equals("userSubReady", true)

I pulled this example from my app, which uses spinners in several places (https://github.com/mizzao/CrowdMapper/tree/master/client/views) as well as the spin.js package for Meteor: https://github.com/SachaG/meteor-spin. Check out the code I linked for more details, if you're interested.

Upvotes: 3

Related Questions