1

I have a form that takes user input and prints the data to a webpage. My goal is to connect to Twitter API and print data based on input result. For example, if the user inputs a certain hashtag, then I want all hashtags with the input data to be printed. I'm able to get input data and print it, I'm also able to print data from a hashtag on click (without input data). But when I'm trying to implement Twitter search with the input form, something is missing.

My form

<form class="form" action="/" method="post" name="form">              
    <input type="text" name="twdata" placeholder="Add data">
    <button type="submit">Submit</button>
</form>

My js with Twitter API (not working)

var theTweets = [];

app.post('/',function(req,res){
    // Grab form data and push it to array
    var twdata = req.body.twdata;

    var params = {
       q: twdata
    }

    client.get('search/tweets', params, getData);

    function getData(err, data, response) {
        var content = data.statuses;
        for (var i = 0; i < content.length; i++) {
            theTweets.push( content[i].text );
        }
    }

    // Display form data on home template
    res.render('home', {twData: theTweets});
});

My js without Twitter API (working)

var formData = [];

app.post('/',function(req,res){
    // Grab form data and push it to array
    var twdata = req.body.twdata;
    formData.push(twdata);

    // Display form data on home template
    res.render('home', {dataInfo: formData});
});

What am I doing wrong?

pistevw
  • 432
  • 4
  • 15

1 Answers1

2

I think the main problem is due you are working with Node.js (Express) and you have to be aware of asynchronous invocation, this is a main problem when working with Node.js, we have to change our mind regarding the execution order since it is not procedural execution. I tried to simulate your program as a Node.js plain application, please check below:

var theTweets  = [];

var res = {
    render: function (page, objData) {
        console.log(page +' '+objData.tweets);
    }
}
var req = {
    body: {
        twdata: '@user'
    }
}

var app = {
    post: function (page, callback) {
        console.log('Page invoked '+page);
        callback(req, res);
    }
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

var client = {
    get : async function (tweets, params, callback) {
        var err = '';
        var data = {statuses: [{text:'tweet01'},{text:'tweet02'}]};
        var response = {};
        await sleep(2000); //code for simulate delay in async call to twitter
        callback(err, data, response);
    }
}

app.post('/', function(req, res) {
    var twdata = req.body.twdata;

    var params = {
       q: twdata
    }

    client.get('search/tweets', params, getData);

    function getData(err, data, response) {
        var content = data.statuses;

         content.forEach ((tweet)=>theTweets.push(tweet.text));

        res.render('home', {'tweets': theTweets});  //correct 
    }
    //res.render('home', {'tweets': theTweets});    //wrong 
});
vpa2
  • 136
  • 4
  • 1
    Actually, I think I solved it just with moving `res.render('home', {'tweets': theTweets});` inside the `getData` function. Thank you very much for the explanation! I have one more question, when I'm changing the params object to `'#' + twdata` to only get hashtags, I also get results without hashtag. For example if I search for nodejs, I get tweets containing both "nodejs" and "#nodejs". Do you have any idea what could be the problem? – pistevw May 04 '18 at 09:50
  • I'd suggest you to see this [link](https://stackoverflow.com/questions/2714471/twitter-api-display-all-tweets-with-a-certain-hashtag). – vpa2 May 04 '18 at 10:30