Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

How to access the result from a variable that is within a function to pass it to the render method in node for pug temp

So I need to access the data that is stored within the GET method that is assigned the variable "TweetTime".

let fiveTweets = tweets[i].text;

This bit of code above is the code I need to then pass to the render method so that my pug template can spit that data out onto the client side, so the user can see. This bit of code goes through a JSON list that was provided by the twitter API. It does infact return the desired text - I just would like to know how I can now grab that data and give it to my pug template. The data that's output on the client side just says [object promise] and not the desired text of the 5 tweets.

Here is my node.js code:

let TweetTime = T.get('statuses/user_timeline', { screen_name: "Neil_Bircumshaw", count: 5 }, function(err, data, response) {

let tweets = data;
for (let i = 0; i < tweets.length; i++){
console.log(tweets[i].text)

let fiveTweets = tweets[i].text;
};
});



app.get("/", (req, res) => {
  res.render("index", {tweet: TweetTime});

Cheers guys for looking :)

1 Answer

The problem is that TweetTime is an asynchronous function. It is not the actual TweetTime you would expect. There are a couple ways of doing this. 1. Would be to place the TweetTime function into your app.get() function. The other would be to take advantage of Express middlewares. The only difference with doing it this way is that You hit the Twitter API each time a request comes in for the app.get("/") route. But in the end this gives you also the ability to spit out more dynamic content depending who is visiting your site.

Below are both ways you can achieve this. 1) Middleware, 2) Placing the Tweet function into your route

  1. Middleware
// First create a simple middlware function that can be used by your routes
function tweetMiddleware(req,res,next) {
  let TweetTime = T.get('statuses/user_timeline', { screen_name: "Neil_Bircumshaw", count: 5 }, function(err, data, response) {
   //Do some basic error handling here
   if(err) {
        return next(err)
   }
   //if no error with the twitter api we keep going
   let tweets = data;
   //I move the tweets out of the loop so I can pass it along after the loop
   let fiveTweets = []
   for (let i = 0; i < tweets.length; i++){
       console.log(tweets[i].text)
       fiveTweets.push(tweets[i].text)
   };
   //once the loop is finished we take the req parameter from the middleware function and give it a property 'tweets'
    req.tweets = fiveTweets;
    //don't forget to call .next() to go to the next handler
    return next();
   });
}

//Now that we have the middleware set up, we can use it in any route we want. By doing that we ensure that the //middleware function is run before your actual route handler
app.get('/', tweetMiddleware, (req,res) => {

     //what is happening is that tweetMiddleware is run first. If there is an error it will go to your error handling function
    //but if there is no error it reaches this function due to 'return next()' in the tweetMiddleware. 
   //You will also have access to the req.tweets property here
   console.log(req.tweets) //should print our your tweets. It is an array so make sure you process is in here if need to
   res.render("index", {tweets: req.tweets}

}

Now the second way of doing is very similar, but instead of having a middlware function, you place the call to Twitter in the app.get().