Oct 15, 2016

Use free News API from newsapi.org with Angularjs

I tried to use news api provided by newsapi.org.
News API is a simple and easy-to-use API that returns JSON metadata for the headlines currently published on a range of news sources and blogs (see their sources here).Up to present their News API can provide live headlines from 66 sources.
Because they support COR so we can make requests directly from the front-end!
We get lastest articles from random source.
// app.js
var app = angular.module("app", ['ngSanitize']);

app.controller("scrapper", function($scope, $http, $q, $timeout) {
    var newsapi_org_apiKey = [
        // newsapi.org API key, you need to sign up for getting your key
        // or you can use API key used for examples in their API docs
        "1bef2b9f1a834a4ba7c821a4f7037c6a",
    ];

    // return promise
    var $getSources = function() {
        return $http.get('https://newsapi.org/v1/sources?language=en');
    };

    var $getArticles = function(source) {
        var deferred = $q.defer();
        $http
            .get('https://newsapi.org/v1/articles?source=' + source + '&sortBy=latest&apiKey=' + newsapi_org_apiKey[0])
            .success(function(data) {
                console.log('get articles successfully');
                deferred.resolve({
                    articles: data.articles
                });
            })
            .error(function(msg, code) {
                deferred.reject(msg);
            });
        return deferred.promise;
    };

    $getSources().then(function(payload) {
        // step 1: retrieve array of source successfully
        $scope.array_of_sources = _.map(payload.data.sources, function(item) {
            return item.id;
        });

        // step 2: get articles from the sources
        // count_attempt counts the number of tries, we initialize it 0
        // the number of tries can't be bigger than array_of_sources' length
        var count_attempt = 0;

        function _try() {
            count_attempt += 1;

            // source assigned randomly from approximately 66 sources
            var source = $scope.array_of_sources[_.random(0, $scope.array_of_sources.length - 1)];

            // get articles from the source
            $getArticles(source).then(function(data) {
                // assign to $scope.articles if success
                $timeout(function() {
                    $scope.articles = data.articles;
                }, 1);

            }, function() {
                // remove source from array_of_sources if on failure
                $scope.array_of_sources = _.reject($scope.array_of_sources, function(item) {
                    return item == source;
                });

                // if total tries is in limit, try another source from array_of_sources
                if (count_attempt < $scope.array_of_sources.length) {
                    _try();
                }
            });
        }
        _try();
    });
});
<html> <head> <meta charset="utf8"> </head> <body> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.5.8/angular-sanitize.min.js"></script> <div ng-app="app" ng-controller="scrapper" class="our-content"> <div class="container" style="padding-top:30px;"> <div class="row"> <div class="col-xs-12 col-lg-8 col-lg-offset-2"> <ul class="list-group" style="border:none;"> <li ng-repeat="article in articles" class="list-group-item" style="border:none;"> <div class="panel panel-info" style="border:none;"> <div class="panel-heading" style="font-size:1.3em;"><a href="{{ article.url }}"><span ng-bind-html="article.title"></span></a></div> <div class="panel-body"> <span ng-bind-html="article.description"></span> <a href="{{ article.url}}" class="btn btn-sm btn-info">More</a> </div> </div> </li> </ul> </div> </div> </div> </div> <script src="app.js"></script> </body> </html>

2 comments:

Post a Comment