Meteor and twitter API


#1

Hi community,

I would like use twitter API for get my last tweet on my Meteor APP with “twit” module NPM.

That my code (server/twit.js), but i get no data :

` Meteor.startup(function () {

    Meteor.methods({

        postTweet: function () {

            Twit = require('twit');

            T = new Twit({
                consumer_key: 'xxx', // API key
                consumer_secret: 'xxx', // API secret
                access_token: 'xxx',
                access_token_secret: 'xxx'
            });

            //  search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
            T.get('search/tweets', { q: 'banana since:2011-11-11', count: 100 }, function(err, data, response) {
                return console.log(data);
            });

        }

    });

});

`

And the code on my client file :

`
Template.layout.rendered = function() {

    Meteor.call('postTweet');

};

`

Do you know why do I retrieve any data ?

Thank you ! :slight_smile:


#2

Check the err and response too


#3

Hi Reoh,

With return console.log(err + ' ' + data + ' ' + response); Nothing appears in my browser console


#4

As your code is written, it will return undefined from the method before the async callback gets the result.

You can use Meteor.wrapAsync to rewrite this in a linear form:

Meteor.methods({

  postTweet: function() {

    const Twit = require('twit');

    const T = new Twit({
      consumer_key: 'xxx', // API key
      consumer_secret: 'xxx', // API secret
      access_token: 'xxx',
      access_token_secret: 'xxx'
    });
    const getTweets = Meteor.wrapAsync(T.get);

    //  search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
    return getTweets('search/tweets', { q: 'banana since:2011-11-11', count: 100 });

  }

});

This should work (untested), although wrapAsync expects the callback to have an (error, result) signature, so the response object will be lost.


#5

It won’t appear in the browser if it’s defined on the server


#6

Hi robfallows,

Thank for your post. I’ve test your code, but how how recovered the client side information ?


#7

There is also work needed on the client, which I missed on the first pass. You need a template helper which is able to handle data returned from a method call (which is not reactive). One way is to do something like this:

Template.mytemplate.onCreated(function() {
  this.result = new ReactiveVar();
  Meteor.call('postTweet', (err,res) => {
    this.result.set(res);
  }
});

Template.mytemplate.helpers({
  tweets() {
    return Template.instance().result.get();
  }
});

and then in your (Blaze) template, iterate over the tweets with something like

{{#each tweets}}
  ...
{{/each}}

#8

Unfortunately I have trouble keeping your idea ^^ I do not see how the client side retrieves data . If I test alert ( ’ this.result ') , it is undefined.

Thank you for your time


#9

The client receives data here:

  Meteor.call('postTweet', (err,res) => {
    this.result.set(res);
  }

When the server-side method returns, the result is available in res in the callback, so if you want to check what’s coming back without a template, you could do this:

  Meteor.call('postTweet', (err,res) => {
    if (err) {
      console.log('Error', err);
    } else {
      console.log('Success', res);
      this.result.set(res);
    }
  }

#10

Ok, i’ve understand, thank for the explication :slight_smile:

I’ve try to check the result without teplate :

Error Object { stack: "Meteor.makeErrorType/errorClass@htt…", error: 500, reason: "Internal server error", details: undefined, message: "Internal server error [500]", errorType: "Meteor.Error" }

And on my console after compilation :

TypeError: Object [object global] has no method 'request'


#11

OK, well it’s hard for me to debug this without using the Twitter API, but you can improve the chances of isolating the issue by changing your method to catch and return errors on the T.get:

Meteor.methods({

  postTweet: function() {

    const Twit = require('twit');

    const T = new Twit({
      consumer_key: 'xxx', // API key
      consumer_secret: 'xxx', // API secret
      access_token: 'xxx',
      access_token_secret: 'xxx'
    });
    const getTweets = Meteor.wrapAsync(T.get);

    //  search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
    try {
      return getTweets('search/tweets', { q: 'banana since:2011-11-11', count: 100 });
    } catch (error) {
      throw new Meteor.Error(error.name, error.message);
    }

  }

});

Your client code (with the logging shown earlier) will report the specific error produced by the T.get.


#12

You can also try binding the wrapAsync context to that of the underlying twit object as follows (sometimes the binding is necessary):

const getTweets = Meteor.wrapAsync(T.get, T);

#13

Hi,

I still can not get it to work . I will continue to search with the indications given in previous posts.

Thank you very much !


#14

Works for me …
Thanks


#15

Works for me too. Thank’s a lot !