Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

  • When the page loads fill monkeyTemplate with monkeys from our external URL.
  • When the user clicks the button, call the external URL again to reload the monkeys.

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.

  • We can populate the template with whatever we return from our Template.monkeyTemplate.monkeys function. How do we fill it with content from an external URL, given that the page will load before the external request is finished?

  • We can get our JSON by using Meteor.HTTP.call("GET", "http://example.com/api/getmonkeys", callback ). Where do we put this request, and what do we put into our callback function in this situation?

  • We can control what happens on the server side and what happens on the client side by using the Meteor.isServer/Meteor.isClient conditions, or by putting our code into files called client and server folders. What code needs to be on the server side vs. the client side?

  • We determine what happens when the button is clicked by attaching a function to Template.monkeyTemplate.events['click #reload']. What goes into our callback function in this situation?

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.

like image 365
supertrue Avatar asked Nov 01 '22 12:11

supertrue


1 Answers

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;
};
like image 94
Hubert OG Avatar answered Nov 11 '22 17:11

Hubert OG