Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version 1.0 release.

Finished testing all GET functions and updated README with
documentation.
  • Loading branch information...
commit df4be25b27e28c1c4d09b5aa3a4aafb24b7921a6 1 parent b4f7827
Mike Fowler authored
Showing with 126 additions and 188 deletions.
  1. +42 −31 README.md
  2. +71 −144 instajam.js
  3. +13 −13 instajam.min.js
73 README.md
View
@@ -5,6 +5,10 @@ Instajam is a JavaScript wrapper for the Instagram API. You provide the access t
(And Instagram provides the gram. Or the pictures. Or... whatever.)
+## Version History
+
+ * 2012/9/10 - Version 1.0, initial release. Supports all GET endpoints (does NOT include adding/removing comments or likes, or setting relationships)
+
## Getting Started
To use Instajam, just include it in your page. For now, Instajam also requires jQuery to facilitate JSONP requests.
@@ -44,7 +48,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Description__: Returns basic information about the authenticated user.
* __Endpoint__: users/self
* __Arguments__:
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.feed(options, callback)
@@ -56,7 +60,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
- count
- min_id
- max_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.liked(options, callback)
@@ -66,7 +70,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* _options (optional)_: A JSON object of options
- count
- max_like_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.get(user_id, callback)
@@ -74,7 +78,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [users/[user-id]](http://instagram.com/developer/endpoints/users/#get_users)
* __Arguments__:
* _user_id_: The user ID to fetch information for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.getRecent(user_id, options, callback)
@@ -88,7 +92,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
- min_timestamp
- max_id
- min_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.search(term, options, callback)
@@ -98,14 +102,14 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* _term_: The search term string
* _options_: A JSON object of options
* count
- * _callback(result, error)_: A callback function
+ * _callback(result)_: A callback function
#### Instajam.user.lookup(username, callback)
* __Description__: Returns basic information for the given username.
* __Arguments__:
* _username_: The username string to look up.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.follows(user_id, callback)
@@ -113,7 +117,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [users/[user-id]/follows](http://instagram.com/developer/endpoints/relationships/#get_users_follows)
* __Arguments__:
* _user_id_: The user ID to fetch information for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.following(user_id, callback)
@@ -121,14 +125,14 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [users/[user-id]/followed-by](http://instagram.com/developer/endpoints/relationships/#get_users_followed_by)
* __Arguments__:
* _user_id_: The user ID to fetch information for.
- * _callback(result, error): A callback function.
+ * _callback(result): A callback function.
#### Instajam.user.requests(callback)
* __Description__: Returns a list of pending follow requests for the currently authenticated user.
* __Endpoint__: [users/self/requested-by](http://instagram.com/developer/endpoints/relationships/#get_incoming_requests)
* __Arguments__:
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.user.getRelationship(user_id, callback)
@@ -136,7 +140,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [users/[user-id]/relationship](http://instagram.com/developer/endpoints/relationships/#get_relationship)
* __Arguments__:
* _user_id_: The user ID to fetch relationship information for.
- * _callback(result, error)
+ * _callback(result)
#### Instajam.user.setRelationship(user_id, action, callback)
@@ -145,7 +149,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Arguments__:
* _user_id_: The user ID to set the relationship for.
* _action_: The relationship action: 'follow', 'unfollow', 'block', 'unblock', 'approve' or 'deny'
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
### Media, Likes and Comments
@@ -155,7 +159,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [media/[media-id]](http://instagram.com/developer/endpoints/media/#get_media)
* __Arguments__:
* _media_id_: The ID of the media to fetch information for.
- * __callback(result, error)__: A callback function.
+ * __callback(result)__: A callback function.
#### Instajam.media.search(options, callback)
@@ -168,14 +172,14 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
- min_timestamp
- max_timestamp
- distance (in meters. max is 5000)
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.popular(callback)
* __Description__: Returns media that is currently popular on Instagram.
* __Endpoint__: [media/popular](http://instagram.com/developer/endpoints/media/#get_media_popular)
* __Arguments__:
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.comments(media_id, callback)
@@ -183,7 +187,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [media/[media-id]/comments](http://instagram.com/developer/endpoints/comments/#get_media_comments)
* __Arguments__:
* _media_id_: The ID of the media to fetch comments for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.addComment(media_id, comment, callback)
@@ -192,8 +196,8 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Arguments__:
* _media_id_: The ID of the media to add a comment to.
* _comment_: The text content of the comment to add.
- * _callback(result, error)_: A callback function.
-
+ * _callback(result)_: A callback function.
+
#### Instajam.media.removeComment(media_id, comment_id, callback)
* __Description__: Removes a comment from a piece of media.
@@ -201,7 +205,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Arguments__:
* _media_id_: The ID of the media to remove a comment from.
* _comment_id_: The ID of the comment to remove from the media.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.likes(media_id, callback)
@@ -209,7 +213,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/media/[media-id]/likes](http://instagram.com/developer/endpoints/media/#get_media_likes)
* __Arguments__:
* _media_id_: The ID of the media to retrieve 'likes' for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.like(media_id, callback)
@@ -217,7 +221,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/media/[media-id]/likes](http://instagram.com/developer/endpoints/media/#post_likes)
* __Arguments__:
* _media_id_: The ID of the media to set a like for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.media.unlike(media_id, callback)
@@ -225,7 +229,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/media/[media-id]/likes](http://instagram.com/developer/endpoints/media/#delete_likes)
* __Arguments__:
* _media_id_: The ID of the media to remove a like for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
### Tags
@@ -235,18 +239,18 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/tags/[tag-name]](http://instagram.com/developer/endpoints/tags/#get_tags)
* __Arguments__:
* _tag_name_: The name of the tag to fetch metadata for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.tag.get(tag_name, options, callback)
* __Description__: Gets media for a tag name.
* __Endpoint__: [/tags/[tag-name]/media/recent](http://instagram.com/developer/endpoints/tags/#get_tags_media_recent)
- * __Arguments__:
+ * __Arguments__:
* _tag_name_: The name of the tag to fetch media for.
* _options_: A JSON object of options.
- min_id
- max_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.tag.search(search_term, callback)
@@ -254,7 +258,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/tags/search](http://instagram.com/developer/endpoints/tags/#get_tags_search)
* __Arguments__:
* _search_term_: The tag name to search for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
### Locations
@@ -264,20 +268,20 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* __Endpoint__: [/locations/[location-id]](http://instagram.com/developer/endpoints/locations/#get_locations)
* __Arguments__:
* _location_id_: The ID of the location to fetch metadata for.
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.location.get(location_id, options, callback)
* __Description__: Gets media for a location.
* __Endpoint__: [/locations/[location-id]/media/recent](http://instagram.com/developer/endpoints/locations/#get_locations_media_recent)
- * __Arguments__:
+ * __Arguments__:
* _location_id_: The ID of the location to fetch media for.
* _options_: A JSON object of options.
- max_timestamp
- min_timestamp
- min_id
- max_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
#### Instajam.location.search(options, callback)
@@ -289,7 +293,7 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
- lng
- distance (in meters, max is 5000)
- foursquare_v2_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
### Geographies
@@ -302,9 +306,16 @@ The [official list of Instagram API endpoints](http://instagram.com/developer/en
* _options_: A JSON object of options.
- count
- min_id
- * _callback(result, error)_: A callback function.
+ * _callback(result)_: A callback function.
+
+## Helper Functions
+#### Instajam.nextPage(pagination_url, callback)
+ * __Description__: For some requests, Instagram will return a data.pagination key with a URL for the next page of results. This function facilitates making that request.
+ * __Arguments__:
+ * _pagination_url_: The URL of the next page of results to fetch.
+ * _callback(result)_: A callback function.
215 instajam.js
View
@@ -21,7 +21,7 @@
* @param {Object} data JSON object of options
* @param {Function} callback A callback function.
*/
- function _request(method, path, data, callback, chain) {
+ function _request(method, path, data, callback) {
var request;
@@ -32,14 +32,19 @@
data = data || {};
// Send the client ID and access token if they are set.
- if(options.auth == "oauth" && options.access_token) {
+ if(options.access_token) {
data.access_token = options.access_token;
}
if(options.client_id) {
data.client_id = options.client_id;
}
- // Handle PUT and DELETE methods.
+ // Return an error if there isn't an access token or client ID
+ if(!data.client_id && !data.access_token) {
+ return callback(new Error('Instajam requires either an access token or a client ID.'));
+ }
+
+ // Handle all CRUD methods.
switch(method) {
case "PUT":
data._method = "PUT";
@@ -59,26 +64,19 @@
data: data
});
- // If the request is part of a chain, return the request object...
- if(chain && typeof chain === "boolean") {
- return request;
- }
- // ... and otherwise just run the callbacks...
- else {
-
- request.done(function(data) {
- if(data.meta.code == 400) {
- throw new Error('Endpoint "' + path + '": ' + data.meta.error_message);
- } else {
- callback(data, null);
- }
- });
-
- request.fail(function(request, status) {
- callback(null, { code: request.status });
- });
+ // Run the callbacks when the deferred
+ // responses come back...
+ request.done(function(data) {
+ if(data.meta.code == 400) {
+ return callback(new Error('Endpoint "' + path + '": ' + data.meta.error_message));
+ } else {
+ return callback(data);
+ }
+ });
- }
+ request.fail(function(request, status) {
+ return callback(new Error('The request failed with status "' + request.status + '"'));
+ });
}
@@ -93,8 +91,8 @@
* @param {Function} callback A callback function.
*/
self: function(callback) {
- _request("GET", "/users/self", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/self", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -112,8 +110,8 @@
options = options || {};
}
- _request("GET", "/users/self/feed", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/self/feed", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -132,8 +130,8 @@
options = options || {};
}
- _request("GET", "/users/self/media/liked", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/self/media/liked", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -143,8 +141,8 @@
* @param {Function} callback A callback function.
*/
get: function(user_id, callback) {
- _request("GET", "/users/" + user_id, null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/" + user_id, null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -163,8 +161,8 @@
options = options || {};
}
- _request("GET", "/users/" + user_id + "/media/recent", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/" + user_id + "/media/recent", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -178,15 +176,15 @@
if(typeof options === "function") {
callback = options;
- options = null;
+ options = {};
} else {
options = options || {};
}
options.q = term;
- _request("GET", "/users/search", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/search", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -197,8 +195,9 @@
* @return {[type]} [description]
*/
lookup: function(username, callback) {
- this.search(username, null, function(result, error) {
- xcallback(result.data[0], error);
+ this.search(username, null, function(result) {
+ if(result.data && result.data.length == 1) result = result.data[0];
+ if(typeof callback === "function") callback(result);
});
},
@@ -208,8 +207,8 @@
* @param {Function} callback A callback function.
*/
follows: function(user_id, callback) {
- _request("GET", "/users/" + user_id + "/follows", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/" + user_id + "/follows", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -219,8 +218,8 @@
* @param {Function} callback A callback function.
*/
following: function(user_id, callback) {
- _request("GET", "/users/" + user_id + "/followed-by", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/" + user_id + "/followed-by", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -229,8 +228,8 @@
* @param {Function} callback A callback function.
*/
requests: function(callback) {
- _request("GET", "/users/self/requested-by", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/self/requested-by", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -240,28 +239,9 @@
* @param {Function} callback A callback function.
*/
getRelationship: function(user_id, callback) {
- _request("GET", "/users/" + user_id + "/relationship", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/users/" + user_id + "/relationship", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
- },
-
- /**
- * Sets the relationship of the current user to a given user ID
- * @param {Integer} user_id The user ID to set the relationship for.
- * @param {String} action The relationship action to set. Accepts: 'follow', 'unfollow', 'block', 'unblock', 'approve' and 'deny'.
- * @param {Function} callback [description]
- */
- setRelationship: function(user_id, action, callback) {
- options = options || {};
- options.action = action;
-
- if(user_id && action) {
- _request("POST", "/users/" + user_id + "/relationship", options, function(result, error) {
- if(typeof callback === "function") callback(result, error);
- });
- } else {
- throw new Error('Endpoint "/users/[user_id]/relationship": user_id and action are required.');
- }
}
};
@@ -278,8 +258,8 @@
* @param {Function} callback A callback function.
*/
get: function(media_id, callback) {
- _request("GET", "/media/" + media_id, null, function(result, error) {
- callback(result, error);
+ _request("GET", "/media/" + media_id, null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -298,8 +278,8 @@
}
if(options.lat && options.lng) {
- _request("GET", "/media/search", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/media/search", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
} else {
throw new Error('Endpoint "/media/search": "lat" and "lng" options are required.');
@@ -311,8 +291,8 @@
* @param {Function} callback A callback function.
*/
popular: function(callback) {
- _request("GET", "/media/popular", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/media/popular", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -322,35 +302,8 @@
* @param {Function} callback A callback function.
*/
comments: function(media_id, callback) {
- _request("GET", "/media/" + media_id + "/comments", null, function(result, error) {
- callback(result, error);
- });
- },
-
- /**
- * Adds a new comment for a given media ID and comment text.
- * @param {Integer} media_id The ID of the media to add a comment for.
- * @param {String} comment The text of the comment to add.
- * @param {Function} callback A callback function.
- */
- addComment: function(media_id, comment, callback) {
- options = {};
- options.text = comment;
-
- _request("POST", "/media/" + media_id + "/comments", options, function(result, error) {
- callback(result, error);
- });
- },
-
- /**
- * Removes a given comment ID from a given media ID
- * @param {Integer} media_id The media ID to remove the comment from.
- * @param {Integer} comment_id The ID of the comment to remove.
- * @param {Function} callback A callback function.
- */
- removeComment: function(media_id, comment_id, callback) {
- _request("DELETE", "/media/" + media_id + "/comments/" + comment_id, null, function(result, error) {
- callback(result, error);
+ _request("GET", "/media/" + media_id + "/comments", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -360,30 +313,8 @@
* @param {Function} callback A callback function.
*/
likes: function(media_id, callback) {
- _request("GET", "/media/" + media_id + "/likes", null, function(result, error) {
- callback(result, error);
- });
- },
-
- /**
- * Sets the 'like' flag for a given media ID.
- * @param {Integer} media_id The ID of the media to like.
- * @param {Function} callback A callback function.
- */
- like: function(media_id, callback) {
- _request("POST", "/media/" + media_id + "/likes", null, function(result, error) {
- callback(result, error);
- });
- },
-
- /**
- * Unsets the 'like' flag for a given media ID
- * @param {Integer} media_id The media ID to unset the 'like' from.
- * @param {Function} callback A callback function.
- */
- unlike: function(media_id, callback) {
- _request("DELETE", "/media/" + media_id + "/likes", null, function(result, error) {
- callback(result, error);
+ _request("GET", "/media/" + media_id + "/likes", null, function(result) {
+ if(typeof callback === "function") callback(result);
});
}
@@ -401,15 +332,15 @@
* @param {Function} callback A callback function.
*/
meta: function(tag_name, callback) {
- _request("GET", "/tags/" + tag_name, null, function(result, error) {
- callback(result, error);
+ _request("GET", "/tags/" + tag_name, null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
/**
* Gets recent media for a given tag name.
* @param {String} tag_name The tag name to request media for.
- * @param {Object} options A JSON object of options.
+ * @param {Object} options A JSON object of options. Accepts: 'min_id' and 'max_id'
* @param {Function} callback A callback function.
*/
get: function(tag_name, options, callback) {
@@ -421,8 +352,8 @@
options = options || {};
}
- _request("GET", "/tags/" + tag_name + "/media/recent", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/tags/" + tag_name + "/media/recent", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -435,8 +366,8 @@
var options = {};
options.q = search_term || "";
- _request("GET", "/tags/search", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/tags/search", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
}
@@ -454,8 +385,8 @@
* @param {Function} callback A callback function.
*/
meta: function(location_id, callback) {
- _request("GET", "/locations/" + location_id, null, function(result, error) {
- callback(result, error);
+ _request("GET", "/locations/" + location_id, null, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -473,8 +404,8 @@
options = options || {};
}
- _request("GET", "/locations/" + location_id + "/media/recent", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/locations/" + location_id + "/media/recent", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
},
@@ -487,8 +418,8 @@
options = options || {};
if((options.lat !== null && options.lng !== null) || options.foursquare_v2_id !== null) {
- _request("GET", "/locations/search", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/locations/search", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
} else {
throw new Error('Endpoint "/locations/search": Either "lat" and "lng", or "foursquare_v2_id" are required.');
@@ -517,8 +448,8 @@
options = options || {};
}
- _request("GET", "/geographies/" + geo_id + "/media/recent", options, function(result, error) {
- callback(result, error);
+ _request("GET", "/geographies/" + geo_id + "/media/recent", options, function(result) {
+ if(typeof callback === "function") callback(result);
});
}
@@ -528,15 +459,11 @@
* Helpers Functions
*/
this.nextPage = function(url, callback) {
- _request("GET", url, null, function(result, error) {
- callback(result, error);
+ _request("GET", url, null, function(result) {
+ if(typeof callback === "function") callback(result);
});
};
- this.chain = function(method, path, options) {
- return _request(method, path, options, null, true);
- };
-
};
}).call(this);
26 instajam.min.js
View
@@ -4,18 +4,18 @@
* Instajam may be freely distributed under the MIT license.
*/
-(function(){var Instajam;var INSTAGRAM_API_BASE='https://api.instagram.com/v1';Instajam=window.Instajam=function(options){options=options||{};function _request(method,path,data,callback,chain){var request;function getURL(){return path.indexOf("http")===0?path:INSTAGRAM_API_BASE+path;}
-data=data||{};if(options.auth=="oauth"&&options.access_token){data.access_token=options.access_token;}
+(function(){var Instajam;var INSTAGRAM_API_BASE='https://api.instagram.com/v1';Instajam=window.Instajam=function(options){options=options||{};function _request(method,path,data,callback){var request;function getURL(){return path.indexOf("http")===0?path:INSTAGRAM_API_BASE+path;}
+data=data||{};if(options.access_token){data.access_token=options.access_token;}
if(options.client_id){data.client_id=options.client_id;}
+if(!data.client_id&&!data.access_token){return callback(new Error('Instajam requires either an access token or a client ID.'));}
switch(method){case"PUT":data._method="PUT";method="POST";break;case"DELETE":data._method="DELETE";method="POST";break;}
-request=$.ajax({type:method,url:getURL(),dataType:'jsonp',data:data});if(chain&&typeof chain==="boolean"){return request;}
-else{request.done(function(data){if(data.meta.code==400){throw new Error('Endpoint "'+path+'": '+data.meta.error_message);}else{callback(data,null);}});request.fail(function(request,status){callback(null,{code:request.status});});}}
-this.user={self:function(callback){_request("GET","/users/self",null,function(result,error){callback(result,error);});},feed:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/users/self/feed",options,function(result,error){callback(result,error);});},liked:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/users/self/media/liked",options,function(result,error){callback(result,error);});},get:function(user_id,callback){_request("GET","/users/"+user_id,null,function(result,error){callback(result,error);});},getRecent:function(user_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/users/"+user_id+"/media/recent",options,function(result,error){callback(result,error);});},search:function(term,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-options.q=term;_request("GET","/users/search",options,function(result,error){callback(result,error);});},lookup:function(username,callback){this.search(username,null,function(result,error){xcallback(result.data[0],error);});},follows:function(user_id,callback){_request("GET","/users/"+user_id+"/follows",null,function(result,error){callback(result,error);});},following:function(user_id,callback){_request("GET","/users/"+user_id+"/followed-by",null,function(result,error){callback(result,error);});},requests:function(callback){_request("GET","/users/self/requested-by",null,function(result,error){callback(result,error);});},getRelationship:function(user_id,callback){_request("GET","/users/"+user_id+"/relationship",null,function(result,error){callback(result,error);});},setRelationship:function(user_id,action,callback){options=options||{};options.action=action;if(user_id&&action){_request("POST","/users/"+user_id+"/relationship",options,function(result,error){if(typeof callback==="function")callback(result,error);});}else{throw new Error('Endpoint "/users/[user_id]/relationship": user_id and action are required.');}}};this.media={get:function(media_id,callback){_request("GET","/media/"+media_id,null,function(result,error){callback(result,error);});},search:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-if(options.lat&&options.lng){_request("GET","/media/search",options,function(result,error){callback(result,error);});}else{throw new Error('Endpoint "/media/search": "lat" and "lng" options are required.');}},popular:function(callback){_request("GET","/media/popular",null,function(result,error){callback(result,error);});},comments:function(media_id,callback){_request("GET","/media/"+media_id+"/comments",null,function(result,error){callback(result,error);});},addComment:function(media_id,comment,callback){options={};options.text=comment;_request("POST","/media/"+media_id+"/comments",options,function(result,error){callback(result,error);});},removeComment:function(media_id,comment_id,callback){_request("DELETE","/media/"+media_id+"/comments/"+comment_id,null,function(result,error){callback(result,error);});},likes:function(media_id,callback){_request("GET","/media/"+media_id+"/likes",null,function(result,error){callback(result,error);});},like:function(media_id,callback){_request("POST","/media/"+media_id+"/likes",null,function(result,error){callback(result,error);});},unlike:function(media_id,callback){_request("DELETE","/media/"+media_id+"/likes",null,function(result,error){callback(result,error);});}};this.tag={meta:function(tag_name,callback){_request("GET","/tags/"+tag_name,null,function(result,error){callback(result,error);});},get:function(tag_name,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/tags/"+tag_name+"/media/recent",options,function(result,error){callback(result,error);});},search:function(search_term,callback){var options={};options.q=search_term||"";_request("GET","/tags/search",options,function(result,error){callback(result,error);});}};this.location={meta:function(location_id,callback){_request("GET","/locations/"+location_id,null,function(result,error){callback(result,error);});},get:function(location_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/locations/"+location_id+"/media/recent",options,function(result,error){callback(result,error);});},search:function(options,callback){options=options||{};if((options.lat!==null&&options.lng!==null)||options.foursquare_v2_id!==null){_request("GET","/locations/search",options,function(result,error){callback(result,error);});}else{throw new Error('Endpoint "/locations/search": Either "lat" and "lng", or "foursquare_v2_id" are required.');}}};this.geography={get:function(geo_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
-_request("GET","/geographies/"+geo_id+"/media/recent",options,function(result,error){callback(result,error);});}};this.nextPage=function(url,callback){_request("GET",url,null,function(result,error){callback(result,error);});};this.chain=function(method,path,options){return _request(method,path,options,null,true);};};}).call(this);
+request=$.ajax({type:method,url:getURL(),dataType:'jsonp',data:data});request.done(function(data){if(data.meta.code==400){return callback(new Error('Endpoint "'+path+'": '+data.meta.error_message));}else{return callback(data);}});request.fail(function(request,status){return callback(new Error('The request failed with status "'+request.status+'"'));});}
+this.user={self:function(callback){_request("GET","/users/self",null,function(result){if(typeof callback==="function")callback(result);});},feed:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/users/self/feed",options,function(result){if(typeof callback==="function")callback(result);});},liked:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/users/self/media/liked",options,function(result){if(typeof callback==="function")callback(result);});},get:function(user_id,callback){_request("GET","/users/"+user_id,null,function(result){if(typeof callback==="function")callback(result);});},getRecent:function(user_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/users/"+user_id+"/media/recent",options,function(result){if(typeof callback==="function")callback(result);});},search:function(term,options,callback){if(typeof options==="function"){callback=options;options={};}else{options=options||{};}
+options.q=term;_request("GET","/users/search",options,function(result){if(typeof callback==="function")callback(result);});},lookup:function(username,callback){this.search(username,null,function(result){if(result.data&&result.data.length==1)result=result.data[0];if(typeof callback==="function")callback(result);});},follows:function(user_id,callback){_request("GET","/users/"+user_id+"/follows",null,function(result){if(typeof callback==="function")callback(result);});},following:function(user_id,callback){_request("GET","/users/"+user_id+"/followed-by",null,function(result){if(typeof callback==="function")callback(result);});},requests:function(callback){_request("GET","/users/self/requested-by",null,function(result){if(typeof callback==="function")callback(result);});},getRelationship:function(user_id,callback){_request("GET","/users/"+user_id+"/relationship",null,function(result){if(typeof callback==="function")callback(result);});}};this.media={get:function(media_id,callback){_request("GET","/media/"+media_id,null,function(result){if(typeof callback==="function")callback(result);});},search:function(options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+if(options.lat&&options.lng){_request("GET","/media/search",options,function(result){if(typeof callback==="function")callback(result);});}else{throw new Error('Endpoint "/media/search": "lat" and "lng" options are required.');}},popular:function(callback){_request("GET","/media/popular",null,function(result){if(typeof callback==="function")callback(result);});},comments:function(media_id,callback){_request("GET","/media/"+media_id+"/comments",null,function(result){if(typeof callback==="function")callback(result);});},likes:function(media_id,callback){_request("GET","/media/"+media_id+"/likes",null,function(result){if(typeof callback==="function")callback(result);});}};this.tag={meta:function(tag_name,callback){_request("GET","/tags/"+tag_name,null,function(result){if(typeof callback==="function")callback(result);});},get:function(tag_name,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/tags/"+tag_name+"/media/recent",options,function(result){if(typeof callback==="function")callback(result);});},search:function(search_term,callback){var options={};options.q=search_term||"";_request("GET","/tags/search",options,function(result){if(typeof callback==="function")callback(result);});}};this.location={meta:function(location_id,callback){_request("GET","/locations/"+location_id,null,function(result){if(typeof callback==="function")callback(result);});},get:function(location_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/locations/"+location_id+"/media/recent",options,function(result){if(typeof callback==="function")callback(result);});},search:function(options,callback){options=options||{};if((options.lat!==null&&options.lng!==null)||options.foursquare_v2_id!==null){_request("GET","/locations/search",options,function(result){if(typeof callback==="function")callback(result);});}else{throw new Error('Endpoint "/locations/search": Either "lat" and "lng", or "foursquare_v2_id" are required.');}}};this.geography={get:function(geo_id,options,callback){if(typeof options==="function"){callback=options;options=null;}else{options=options||{};}
+_request("GET","/geographies/"+geo_id+"/media/recent",options,function(result){if(typeof callback==="function")callback(result);});}};this.nextPage=function(url,callback){_request("GET",url,null,function(result){if(typeof callback==="function")callback(result);});};};}).call(this);
Please sign in to comment.
Something went wrong with that request. Please try again.