Rendering Tweets with AngularJS and Node.js

By
Tuesday, 5 August 2014

AngularJS is a JavaScript framework gaining popularity in the developer community. It offers a unique toolset that allows you to build client-side applications with fewer lines of code. In particular, Angular’s data-binding features are extremely useful for rendering data from the Twitter REST API.

The example below uses AngularJS in conjunction with the Twitter REST API to render embedded Tweets. First, request Tweets from the Twitter REST API. We use Node.js with the Twit Twitter API client to retrieve Tweets from the statuses/user_timeline endpoint. To keep the code simple and easy to follow, error handling is not included. The full source code can be found on our GitHub page.

  params = {
    screen_name: req.params.user, // the user id passed in as part of the route
    count: TWEET_COUNT // how many tweets to return
  };

  // request data 
  twitter.get(USER_TIMELINE_URL, params, function (err, data, resp) {

    tweets = data;

    var i = 0, len = tweets.length;

    for(i; i < len; i++) {
      getOEmbed(tweets[i]);
    }
  });

For each Tweet in the response, the HTML required to create embedded Tweets is requested from the statuses/oembed endpoint using the Tweet ID. The Tweet data is added to a new property called oEmbed on each Tweet. In a production environment, this data should be cached.

  function getOEmbed (tweet) {

    // oEmbed request params
    var params = {
      "id": tweet.id_str,
      "maxwidth": MAX_WIDTH,
      "hide_thread": true,
      "omit_script": true
    };

    // request data 
    twitter.get(OEMBED_URL, params, function (err, data, resp) {

      tweet.oEmbed = data;
      oEmbedTweets.push(tweet);

      // do we have oEmbed HTML for all Tweets?
      if (oEmbedTweets.length == tweets.length) {
        res.setHeader('Content-Type', 'application/json');
        res.send(oEmbedTweets);
      }
    });
  }

This data is exposed by an endpoint provided by the Node.js app and can be consumed by Angular on the front end. Angular makes it easy to render JSON data in the DOM. To get started with our Angular app, we will now create a controller and request the Tweets with a resource.

    function getTweets (paging) {

      var params = {
        action: 'user_timeline',
        user: $scope.username
      };

      // create Tweet data resource
      $scope.tweets = $resource('/tweets/:action/:user', params);

      // GET request using the resource
      $scope.tweets.query( { }, function (res) {

        $scope.tweetsResult = $scope.tweetsResult.concat(res);

        // render tweets with widgets.js
        $timeout(function () {
          twttr.widgets.load();
        }, 30);
      });
    }

The data is then assigned to the $scope.tweetsResult. The Angular view will automatically render this data using data-binding defined in the HTML template. In the HTML of the app, use the ngRepeat directive to loop through all Tweets in the model. Use the ngBindHtml directive to render the oEmbed HTML in each Tweet object. The ngBindHtml directive uses Angular’s default settings to sanitize HTML in a model. A delayed call to twttr.widgets.load()provided by widgets.js will render the embedded Tweets added to the DOM.

  <div ng-repeat="tweet in tweetsResult" class="tweet-item">

    <!-- sanitized HTML binding -->
    <div ng-bind-html="tweet.oEmbed.html"></div>

    <!-- binding to Tweet source property -->
    <div class="tweet-details">
      Source: <span ng-bind-html="tweet.source"></span>

      <!-- play around with rendering different Tweet properties -->
      <!-- <p>{{tweet.user.screen_name}}</p> -->
      <!-- <p>{{tweet.text}}</p> -->
    </div>
  </div>

The Tweet object also has fully-hydrated user objects and an entities property that contains information about attached photos, links and @mentions. Play around with the Twitter data by binding it to different properties of the Tweet object in the HTML.

While this example only touches on the data-binding aspect, Angular offers much more. This includes dependency injection and directives, both of which can help you create custom HTML elements. Download the full source code on GitHub, as it demonstrates two-way data binding with a form as well as working with Twitter timeline data.

For more information on the oEmbed API, check out our pro tip post.