Setting up a Wikipedia Factory in Angular

API's make your tiny little app look like a mother fuckin sorcerer. With a few well placed $http calls, you can live the Dev dream and have all the data you want without actually having to go get it yourself. To do that, I'm going to go through how to set up a basic factory in Angular to run some queries to Wikipedia that will grab an image and the article extract for a set of titles.

Set up Factory

First, declare a factory onto an app module. Our factory will expose one function to its subscribing controllers called getWiki.

angular.module('angularApp')  
  .factory('wikiFactory', function($http){

  var getWiki = function(title){};

  return {
    getWiki: getWiki
  }
});

Build our Query URL

Next up we have to navigate the wilds of the Wiki API and create a url that will pull up our images and extract. First, we add a variable defining the base Wiki API url. Then, we will define a helper function which will take an object and convert it into an appropriately parsed URL parameters string. This will allow us to conveniently add in all our search parameters using object notation in our getWiki function.

    var wikiUrl = "http://en.wikipedia.org/w/api.php?action=query&format=json&callback=JSON_CALLBACK";

    var buildQuery = function(obj) {
      var url = wikiUrl;
      for (var key in obj) {
        url += '&' + key + '=' + obj[key];
      }
      return url;
    };

Run some $http

Our getWiki function will make use of the angular $http module and promises to deal with all the async magic. We will pass an object defining all of our search parameters, use the buildQuery helper function to collate them into a searchable string, and then send off our request to Wikipedia.

Note on CORS

To avoid Cross Origin issues, we'll set our method to jsonp so that everyone plays nice together.

  var getWiki = function(titlesArray) {
      var url = buildQuery({
        titles: titlesArray.join('|'),
        prop: "pageimages|extracts",
        pithumbsize: 500,
        redirects: true,
        exintro: true,
        explaintext: true,
      });

      return $http({
        url: url,
        method: 'jsonp'
      }).then(function(results) {
        return results.data;
      });
    };

This code will make a query for all titles contained in the passed in array. It will grab an image of size 500, or closest, and the extract parsed into a string. Redirects is set to true so if the title leads to a redirect, the redirect article will be sent.

Tie it All Together

So toss that little factory in there and you're good to go querying Wikipedia to your app's heart's content! Beware that the data that comes back is organized based on the Wiki page id, so you'll have to do a little digging to get at the good stuff.

angular.module('angularApp')  
  .factory('wikiFactory', function($http) {

    var wikiUrl = "http://en.wikipedia.org/w/api.php?action=query&format=json&callback=JSON_CALLBACK";

    var buildQuery = function(obj) {
      var url = wikiUrl;
      for (var key in obj) {
        url += '&' + key + '=' + obj[key];
      }
      return url;
    };

    var getWiki = function(titles) {
      var url = buildQuery({
        titles: titles.join('|'),
        prop: "pageimages|extracts",
        pithumbsize: 500,
        redirects: true,
        exintro: true,
        explaintext: true,
      });

      return $http({
        url: url,
        method: 'jsonp'
      }).then(function(results) {
        return results.data;
      });
    };

    return {
      getWiki: getWiki
    }
  });