City Photo Finder

Using Foursquare API, Ajax, and Promises

Posted on February 4, 2016 in webdev

Foursquare API

Foursquare's API lets you find venues in any given city. It also lets you find photos of any venue given its unique id. I combined these two endpoints:

api.foursquare.com/v2/venues/search/ api.foursquare.com/v2/venues/{venue_id}/photos

to make a tool that finds pictures from any city.

Promises

I'm still getting my head wrapped around what JS Promises can do. At a basic level, a promise represents a value that will exist in the future. To construct a Promise, you pass it one argument--a callback with two parameters, resolve and reject. Once a promise is defined and returned, you can chain functions to it that run only when the promise has failed or been resolved.

Here's a good example I found showing the basic functionality of a promise:

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

(Source: html5rocks.com)

Now, with these resolve and reject states, you can do something like this:

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});

When the promise is resolved then the function will be called.

This is useful for ajax calls. I used the resolve states of promises to chain multiple functions together in this project:

function downloadPhotosByLocation(loc){

  // find venues and get the pictures from each one
	var endpoint = 'venues/search';
	var url = makeUrl(endpoint, ['near', loc]);

	return getJSON(url).then(function(response) {
	  return response.response.venues;
	}).then(function(venues){
		return venues;
	}).catch(function(err){
		console.log('Error!', err);
	}).then(function(venues){
		storeVenues(venues);

		for(var i = 0; i < venues.length; i++){
			getPictures(venues[i]);
		};
	});
}

getJSON() is just a helper function that calls get(), which returns a promise. That's why I could attach .then(function()... to getJSON().

Here is my get() function which I use to make all my GET requests:

function get(url) {

  return new Promise(function(resolve, reject) {

    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {

      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }

    };

    req.onerror = function() {
      reject(Error("Network Error"));
    };

    req.send();
  });
}



See it on Github


comments powered by Disqus