supertrue
supertrue

Reputation: 2099

Basic pattern: Populate a template with JSON from an external URL in Meteor

I am struggling to figure out the basic pattern for populating a template with data from a call to an external API in Meteor.

These are the elements in play

  1. A fresh Meteor project, created by running meteor create monkeyproject
  2. The URL of an external API that returns a JSON array. Let's say it's example.com/api/getmonkeys. It returns an array of monkeys, each with a different name.
  3. A Handlebar template called monkeyTemplate with an {{#each}} loop. Let's say it's this:

    <template name="monkeyTemplate">
        {{# each monkeys}}
            One of our monkeys is named {{name}}. <br>
        {{/each}}
        <input type="button" id="reload" value="Reload monkeys" />
    </template>
    

What I want to happen

The question

What is a standard pattern for doing the above in Meteor? At the risk of cluttering up the question, I'll include some starting points, as I understand them.

I will refrain from cluttering up the question with my crappy code. I am not looking for anyone to write or rewrite an application for me—I am just looking for the guidelines, standard patterns, best practices, and gotchas. Hopefully this will be instructive to other beginners as well.

Upvotes: 5

Views: 1195

Answers (1)

Hubert OG
Hubert OG

Reputation: 19544

I'm not sure if this is the "standard" template, but it serves the purpose pretty well.

  • Set up two data helpers for the template, monkeys and loading. First one will display the actual data once it's fetched, the latter will be responsible for notifying user that the data is not yet fetched.
  • Set up a dependency for these helpers.
  • In created function of the template, set loading helper to true and fetch the data with HTTP call.
  • In the callback, set the template data and fire the dependency.

html

<template name="monkeys">
   {{#if loading}}
       <div>Loading...</div>
   {{/if}}
   {{#if error}}
       <div>Error!</div>
   {{/if}}
   {{#each monkeys}}
       <div>{{name}}</div>
   {{/each}}
   <div><button class="monkeys-reloadMonkeys">Reload</button></div>
</template>

js

var array = null;
var dep = new Deps.Dependency();

 

Template.monkeys.created = function() {
    reloadMonkeys();
};

Template.monkeys.events({
    'click .monkeys-reloadButton': function(e,t) {
         reloadMonkeys();
    };
});

var reloadMonkeys = function() {
    array = null;
    dep.changed();
    HTTP.get('http://example.com/api/getmonkeys', function(error, result) {
        if(!error && result) {
            array = result;
        } else {
            array = 0;
        }
        dep.changed();
    });
};

 

Template.monkeys.monkeys = function() {
    dep.depend();
    return array ? array : [];
};

Template.monkeys.loading = function() {
    dep.depend();
    return array === null;
};

Template.monkeys.error = function() {
    dep.depend();
    return array === 0;
};

Upvotes: 2

Related Questions