ptg
24
Chapter 2 Getting Basic MySpace Data
Error Handling
JavaScript errors from apps seem to be an all-too-common occurrence, but they don’t
have to be. Most developers don’t expect errors to occur, and so they don’t test or pre-
pare for them as a result, but errors do happen.Your best defense against them is to admit
that yes, they do occur, and yes, you need to be ready for them.
OpenSocial offers a few functions you can use to deal with errors. In the following
example we check for errors before we parse the response for data. If an error is found,
the response data isn’t parsed.
/**
* Check if the response had an error; if it did, log it and if
* it was an INTERNAL_ERROR attempt to retry the request
* @param {opensocial.DataResponse} data
*/
function requestHadError(data){
// Return true if data is null or undefined
if(!data) return true;
// Check the opensocial.DataResponse for the global error flag
if(data.hadError()){
// Find the specific opensocial.ResponseItem that had the error
var ri = data.get(Tic-Tac-Toe.RequestKeys.VIEWER);
// If the view name passed in is in the supported hash table
if(supported[view]){
// Request to navigate to that view
gadgets.views.requestNavigateTo(supported[view]);
}
}
This function takes in the name of the view to navigate to and then gets the list of
currently supported views by calling
gadgets.views.getSupportedViews()
. This
function returns a hash table of
gadgets.views.View
objects, keyed by the names of
the views.
If the list of supported views contains the specified view,
requestNavigateTo
is
invoked and the
View
object is passed in. To make use of the
rNT
function, you might
do something like this in the onclick handler of a button:
rNT(gadgets.views.ViewType.CANVAS);
That will cause the browser to navigate to the app’s Canvas page.
24
Chapter 2 Getting Basic MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
25
if(ri && ri.hadError()){
// Output the error message
log(ri.getErrorMessage());
// Check the error code; an INTERNAL_ERROR can simply mean
// network congestion or MySpace server instability
if(opensocial.ResponseItem.Error.INTERNAL_ERROR === ri.getErrorCode()){
// Retry the request a certain number of times; make
// sure you don't create an infinite loop here!
if(retries > 0){
retries--;
window.setTimeout(getInitialData, 1000);
}
}
}
return true;
}
return false;
}
First, we check if the response is null or undefined, and then check if the global error
flag was set in the
DataResponse
object by calling the object’s
hadError()
function.
This flag is set if any of the requests had an error. Each
ResponseItem
has an error flag
as well, so we’ll need to check each
ResponseItem
in order to find out which request
had the error, if the global flag was set. We do this by calling the
ResponseItem
’s
hadError()
function. In this case we had only one request, so there is only one
ResponseItem
, but in the event of multiple
ResponseItem
objects we would check
each one in turn to determine its error state.
Similar to an
opensocial.Enum
object that has two types of data, one for display and
one for logical comparisons, each
opensocial.ResponseItem
that encounters an error
also has two types of data.The error message, accessed by
getErrorMessage()
, is an
arbitrary string that should describe the error and help you debug what happened.The
error code, accessed by
getErrorCode()
, matches up to one of the codes found in the
opensocial.ResponseItem.Error
enum. Common causes for each type of error code
may be found in Table 2.4.
You’ll notice that we also attempted to retry the request in the event of an
INTERNAL_ERROR
.This is because an
INTERNAL_ERROR
can sometimes occur because of
network congestion or other temporary problems.Your request might succeed if you
wait a second or so and try again.
Error Handling
25
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
26
Chapter 2 Getting Basic MySpace Data
Handling errors offers two benefits:
n
There are no embarrassing JavaScript errors when you try to retrieve objects that
don’t exist.
n
There’s a possibility that you can recover from your error by retrying the request.
Table 2.4 Common Error Code Causes
Common Error Codes Causes
opensocial.ResponseItem.Error.
The most common cause of this error is that
BAD_REQUEST
some part of your request didn’t make
sense to the container. For example, you
passed in a negative value that should be
positive, you didn’t supply a required field,
or you passed in an invalid ID for a particu-
lar request.
opensocial.ResponseItem.Error.
This error is returned only when the server
FORBIDDEN
responds with a status code of 403 and is
not commonly seen.
opensocial.ResponseItem.Error.
This is a catchall error that typically occurs
INTERNAL_ERROR
when something unknown happens on the
MySpace side of the request. As such, it
should be intermittent. It can also occur in
opensocial.requestPermission
(a topic
we’ll cover in the section on requesting per-
missions in Chapter 3) if a permission was
requested but no new permission was
granted, or if the server returned an
unknown status code.
opensocial.ResponseItem.Error.
This error is returned if you’ve requested
NOT_IMPLEMENTED
some OpenSocial functionality that MySpace
doesn’t support. If you receive this error,
either the entire function you’re calling isn’t
available, or some parameter in a request
isn’t supported. An example of the latter
would be that you requested an
opensocial.Person
field that isn’t
supported.
opensocial.ResponseItem.Error.
This error most commonly happens when
UNAUTHORIZED
you’ve requested data to which you don’t
have access. It may be possible to use
opensocial.requestPermission
to ask
the user to grant your app access to the
data. Again, see Chapter 3 for details.
26
Chapter 2 Getting Basic MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Warning
When retrying your request after an error, be careful you don’t code yourself into an infinite
loop! It’s best to keep a retry counter as we do in the code shown previously.
Summary
In this chapter we covered the basic flow of an OpenSocial application, focusing on the
process of accessing data on the API and OpenSocial’s request/response pattern.We also
defined an
opensocial.Person
object—what it is, how to get it, and what to do with it.
This request/response pattern is the foundation of any OpenSocial app.You will use it
every time you request data from the server, so we hope you were paying attention.
Note
Code listings and/or code examples for this chapter and every other chapter can be found
on our Google Code page under .
27
Summary
27
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
This page intentionally left blank
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
3
Getting Additional
MySpace Data
I
n the preceding chapter we covered how to fetch and make use of the
Person
object
on the MySpace platform. But there’s a lot more data out there—such as the user’s
friend list and the photos the user has uploaded. It’s the use of all this data that will
propel your app from a lifeless Web game to a dynamic and social application with viral
potential.
Most application developers use the friend list in order to spread and share their
applications (see Chapter 5, Communication and Viral Features, to learn how) and other
endpoints like albums and videos to make their apps more personal and engaging for the
user.
In this chapter we’ll do just that by covering how to access and use your users’ data to
make your app more dynamic and appealing.We’ll show how to retrieve your users’
friends; use paging to sort, sift, and display the data; as well as explore viewing albums,
photos, and videos.We’ll also discuss some extras, such as how to check whether a user
already has an app installed and how to check for and request permissions from a user. As
we start to request more and more sensitive data, such as a user’s photos, permissions will
start to come into play more and more.
From now on, our Tic-Tac-Toe game is no longer a boring JavaScript applet. It’s a
feature-packed app that actually uses the power of the MySpace social network.
How to Fetch a Friend List and Make Use
of the Data
This section will show you how to fetch a list of friends and then page through that list.
You’ll also learn the various ways you can sort and filter a friend list, such as restricting it
to only friends who have the app installed.
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
In our example Tic-Tac-Toe app, we’ll use the list of friends in two ways:
n
Provide a list of all the Viewer’s friends so the Viewer can send invitations to those
friends to add the app.
n
Provide a list of friends who already have the app installed so the Viewer can
challenge those friends to a game of Tic-Tac-Toe.
The actual invitation sending and game play challenges will be covered in Chapter 5,
Communication and Viral Features.This section will lay the foundation for those
functions by showing you how to pull out the friend list and filter it accordingly.
A Quick JavaScript Lesson
Up until now, we’ve kept the code simple by sticking to OpenSocial-specific JavaScript.
We did this by separating the Tic-Tac-Toe game logic from the OpenSocial code and keep-
ing everything globally namespaced (meaning the code can be called from anywhere; this
is its “scope” in programming terms).
Moving forward, our app will become more and more complex. This added complexity
requires us to start introducing more advanced JavaScript techniques such as object
notation and object-oriented programming.
This is not a book on JavaScript programming but on how to build dynamic OpenSocial
apps on MySpace. You’ll find, however, that you’ll learn a lot about JavaScript along the way!
To this end you’ll start to notice the use of the
TTT
namespace. This is where we’ll
keep all the code for game-specific functionality. For example, in Chapter 2, Getting Basic
MySpace Data, we provided a key of
"v"
when we requested the Viewer data. In this
chapter we move all of those keys into an enum:
TTT.RequestKeys
. So instead of
using key
"v"
, we use key
TTT.RequestKeys.VIEWER
.
We concentrate on the OpenSocial code in this book, but feel free to dig into the full
code listings found at our Google Code site: .
Getting the Friend List
This is the same request/response idea from Chapter 2, Getting Basic MySpace Data,
that helps define OpenSocial. In fact, the friend list is just an
opensocial.Collection
of
opensocial.Person
objects, but instead of dealing with just one
Person
as in
Chapter 2, we’re dealing with a list of them.
There are two major differences between fetching a single
Person
and fetching a
friend list:
n
Call
newFetchPeopleRequest
instead of
newFetchPersonRequest
.
n
Instead of passing in an ID (such as Viewer or Owner), pass in an
opensocial.IdSpec
object.
An
IdSpec
object is a different way to specify a group of IDs. It requires you to
define two parameters: the user ID and the network distance.The user ID specifies the
30
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
context for the
IdSpec
—basically letting MySpace know if you’re asking for a group
involving the Owner or the Viewer. MySpace supports the contexts of only Viewer and
Owner. In other words, you can’t get a friend list for a random user; it has to be for
either the Viewer or the Owner.
The network distance defines how far out the connections go. For example, specify-
ing a network distance of 0 would denote just the Owner or the Viewer, and a network
distance of 1 would denote the friends of the Owner or the Viewer. At this time
MySpace supports a network distance only to a maximum of 1, so you can’t fetch the
friends of your friends.
Let’s create a
fetchFriendList()
function to get a basic friend list.This function
wraps the
newFetchPeopleRequest
. Our example is heavily simplified, though, so it
isn’t our final version of the function. We’ll expand on it as we see what else you can do
with a friend list. We’ll be inserting this function into the code of our Tic-Tac-Toe app
found in Chapter 2. For those of you following along at home, place this function
anywhere in the script tag in that code:
function fetchFriendList(callback){
// Create the IdSpec object
var params = {};
params[opensocial.IdSpec.Field.USER_ID] =
opensocial.IdSpec.PersonId.VIEWER;
params[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1;
var idspec = opensocial.newIdSpec(params);
// Create the DataRequest object
var request = opensocial.newDataRequest();
// Add the request to the queue
request.add(request.newFetchPeopleRequest(idspec),
TTT.RequestKeys.VIEWER_FRIENDS);
// Send it off
request.send(callback);
}
First, the
IdSpec
object is created using a user ID of
VIEWER
and a network distance of
1 to specify that we want the friends of the Viewer. Next, an
opensocial.DataRequest
object is instantiated and the request is added to the queue with a custom key of
TTT.RequestKeys.VIEWER_FRIENDS
. Finally, the request is sent off (and the response will
find its way back to the specified callback).
Filters and Sorts
The first example we showed you just fetches an arbitrary subset of friends of the Viewer.
This list is typically returned in the order in which the friendships were made and is not
How to Fetch a Friend List and Make Use of the Data
31
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
terribly complex. OpenSocial, however, defines a number of ways to sort and filter
fetched lists, making them a lot more useful. Before getting to the code, let’s look at the
available options.The MySpace-supported filter types and sorts are shown in Table 3.1.
Let’s revisit the
fetchFriendList()
function, but this time with support for sorts
and filters. Again, we’re not quite at the final version of our function, but this code
brings us a step closer:
function fetchFriendList(callback, filter, sort){
// Create the IdSpec object
var params = {};
params[opensocial.IdSpec.Field.USER_ID] =
opensocial.IdSpec.PersonId.VIEWER;
params[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1;
var idspec = opensocial.newIdSpec(params);
params = {};
// Add any filters
if(filter && filter.length > 0){
params[opensocial.DataRequest.PeopleRequestFields.FILTER] = filter;
}
// Add any sorts
if(sort && sort.length > 0){
params[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = sort;
}
// Create the DataRequest object
var request = opensocial.newDataRequest();
// Add the request to the queue
request.add(request.newFetchPeopleRequest(idspec),
TTT.RequestKeys.VIEWER_FRIENDS);
// Send it off
request.send(callback);
}
You can see that the filters and sorts are specified by adding
opensocial.
DataRequest.PeopleRequestFields.FILTER
and
opensocial.DataRequest.
PeopleRequestFields.SORT_ORDER
to the parameters.
Paging
According to the OpenSocial spec, the default number of items returned for a request is 20.
That means our
fetchFriendList()
function returns the first 20 friends in the list. But
what if a user has more than 20 friends? Enter paging.
32
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Paging is a way to get a large collection of data one chunk at a time.That means that
once we have fetched friends 1 to 20, we can then fetch friends 21 to 40, then 41 to 60,
and so on. OpenSocial also provides a way to specify which chunk of friends you want
for a given request.
To demonstrate paging, let’s expand one final time on our
fetchFriendList()
function:
function fetchFriendList(first, max, callback, filter, sort){
// Create the IdSpec object
var params = {};
params[opensocial.IdSpec.Field.USER_ID] =
opensocial.IdSpec.PersonId.VIEWER;
Table 3.1 Supported Friend List Filters and Sorts on MySpace
Filter Type Details
opensocial.DataRequest.FilterType.
The default filter, essentially no filter
ALL
opensocial.DataRequest.FilterType.
Fetches only those friends who have
HAS_APP
added the app
opensocial.DataRequest.FilterType.
MySpace allows users to define top or
TOP_FRIENDS
favorite friends; these are the
friends who appear at the top of the
user’s Friend Space, and this filter
fetches only those friends.
MyOpenSpace.DataRequest.FilterType.
Fetches only friends who
ONLINE_FRIENDS
are currently online
MyOpenSpace.DataRequest.SortOrder.ID
Not a filter; allows you to sort a friend
list by ID (ascending). Note that this
sort is applied after the page is
fetched, so it doesn’t take the
user’s entire friend list, sort it, and
return a particular page. What
happens is that a page of friends is
taken and that list is sorted. This is
not particularly useful.
opensocial.DataRequest.SortOrder.NAME
Another sort; sorts the returned list by
nickname (ascending). Like the pre-
ceding sort, this one isn’t the most
useful as the entire friend list isn’t
sorted up front, only the returned
page.
How to Fetch a Friend List and Make Use of the Data
33
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
params[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1;
var idspec = opensocial.newIdSpec(params);
params = {};
// Set the paging parameters
if(first){
params[opensocial.DataRequest.PeopleRequestFields.FIRST] = first;
}
if(max){
params[opensocial.DataRequest.PeopleRequestFields.MAX] = max;
}
// Add any filters
if(filter && filter.length > 0){
params[opensocial.DataRequest.PeopleRequestFields.FILTER] = filter;
}
// Add any sorts
if(sort && sort.length > 0){
params[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = sort;
}
// Create the DataRequest object
var request = opensocial.newDataRequest();
// Add the request to the queue
request.add(request.newFetchPeopleRequest(idspec),
TTT.RequestKeys.VIEWER_FRIENDS);
// Send it off
request.send(callback);
}
You’ll notice that
opensocial.DataRequest.PeopleRequestFields.FIRST
and
opensocial.DataRequest.PeopleRequestFields.MAX
have been added to the
parameters.
MAX
defines the maximum number of friends to fetch at a time, so if you
specified a
MAX
of 100 (the maximum allowed by MySpace), you’d get the friend list in
chunks of 100.
FIRST
specifies which friend to start fetching from, so if you specified
that
FIRST
is 201 and
MAX
is 100, you’d get friends 201 to 300.
That means you’ll want to keep
MAX
at a constant value and increment
FIRST
by that
value for each request.Assume we define
MAX
to be 50; we’d start out with a value of
FIRST
as 1. If the user requested the next page, we’d change
FIRST
to 51, and then 101,
and so forth.The API provides you with the total number of friends in the list (in addi-
tion to the number fetched with the current request) to aid you in paging.
In our Tic-Tac-Toe app we fetch 20 friends at a time. You can see a successful friend
list request in Figure 3.1.
34
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Let’s take a look at the paging object we used:
TTT.Lists.Pager = {
pager_wrap:"<div class='pager'>{0}</div>",
pager_prev:"<span onclick='TTT.Lists.Pager.prev();'><< prev</span> ",
pager_next:" <span onclick=’TTT.Lists.Pager.next();’>next >></span>",
page_size:20,
getMarkUp:function(){
var current_list = TTT.Lists.getCurrentList();
if(current_list.list.length < this.page_size){
// If the length is less than the amount requested
// there is only one page, no need for a pager
return "";
}
var markup = "";
if(current_list.first > this.page_size){
// If the first index is greater than the size of
// a page then there will be a previous page
markup += this.pager_prev;
}
if(current_list.total >
current_list.first + current_list.list.length - 1){
// If the total number of records is greater than
Figure 3.1
Screen shot of a successful friend list request.
How to Fetch a Friend List and Make Use of the Data
35
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
// the current index, plus the amount in the current
// result set, minus 1, then there's another page.
// e.g., first = 1, current set = 20, total = 55
// 1 + 20 - 1 = 20 records fetched, < 55
// e.g., first = 21, current set = 20, total = 55
// 21 + 20 - 1 = 40 records fetched, < 55
// e.g., first = 41, current set = 10, total = 55
// 41 + 15 - 1 = 55 records fetched, == 55
markup += this.pager_next;
}
if(markup.length > 0){
markup = this.pager_wrap.replace("{0}", markup);
}
return markup;
},
prev:function(){
var current_list = TTT.Lists.getCurrentList();
current_list.first -= this.page_size;
fetchFriends(current_list.list_type);
},
next:function(){
var current_list = TTT.Lists.getCurrentList();
current_list.first += this.page_size;
fetchFriends(current_list.list_type);
}
};
The
Pager
object in our Tic-Tac-Toe app does three things:
1. Provides HTML markup for Next and Prev buttons that we can use to allow the
user to actually navigate between pages.
2. Stores the value of
FIRST
that is the current value.
3. Handles what happens when the Next and Prev buttons are clicked.
Meanwhile, the
getMarkUp()
function handles the actual paging algorithm. With
this function there are three possible outcomes:
1. The number of records fetched is less than the number requested (
MAX
). This
means there is only one page of data, so no paging is required.
2. The value of
FIRST
is greater than the size of a page.Therefore, there is at least
one previous page, so we need the Prev link.
3. The total number of friends is greater than all the friends fetched so far. Therefore,
there are more friends who can be fetched, so a Next link must be added.
36
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Tip: Advanced Technique
You’ll see as we progress through this chapter that our Tic-Tac-Toe app presents the user
with three lists. One is the entire friend list, one is the list of friends who have the app
installed, and the third is the list of photos the user has uploaded to his or her MySpace
Profile. The lists all appear fairly similar—each item is in a box that can be clicked, each
has a picture, and each has some text underneath. If all these lists are so similar, why not
abstract the code so you can use the same functions to generate all three lists?
This is exactly what we did. We created a
TTT.List
object to represent a list, a
TTT.Lists
object that keeps track of all the current lists that are on the page
(note the s at the end), and a
TTT.ListTypes
enum to differentiate the types of lists.
The
TTT.List
object contains the status of a particular list, including which type it is. It
also has references to the actual Document Object Model (DOM) elements that get
displayed, the OpenSocial objects that were fetched, paging parameters, what to do when
it’s clicked, and the keys used to access the stored OpenSocial data. It’s essentially an
interface for what a list should look like.
The
TTT.Lists
object stores the collection of lists and which list is currently selected.
We also do something similar for the set of tabs along the top of the app. Check out the
TTT.Tab
and
TTT.Tabs
objects for more abstraction fun!
Using the Data
We’ve now defined a function that wraps the OpenSocial function
newFetchPeopleRequest()
. In our Tic-Tac-Toe app we call that function like so:
function fetchFriends(list_type){
// Make sure the correct list is set
TTT.Lists.setCurrentList(list_type);
// Get the current list
var current_list = TTT.Lists.getCurrentList();
// Do we need to add any filters?
var filter = "";
if(TTT.ListTypes.HASAPP_FRIENDS === list_type){
// Add the HAS_APP filter
filter = opensocial.DataRequest.FilterType.HAS_APP;
}
// Call the fetch friends wrapper
fetchFriendList(current_list.first, current_list.max,
TTT.Lists.callback, filter);
}
First we get a reference to the currently selected list. If it’s the list of friends who have
the app installed, we add that filter (
TTT.ListTypes.HASAPP_FRIENDS
) and send it into
the wrapper.
How to Fetch a Friend List and Make Use of the Data
37
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
The callback function we passed in,
TTT.Lists.callback
, will be executed once
the friend request has been made and the API responds with some data. Let’s take a look
at the callback function’s code and walk through it in detail. You’ll recognize a lot of the
OpenSocial aspects from when we discussed callbacks and data parsing in Chapter 2,
Getting Basic MySpace Data:
TTT.Lists.callback = function(response){
var current_list = TTT.Lists.getCurrentList();
var retryRequest = function(){
current_list.retries--;
window.setTimeout(fetchFriends, 250);
};
// Check for an error
if(!response.hadError()){
var data = null;
// Loop through the available keys to
// find the actual data in the response
for(var key in TTT.RequestKeys){
if(response.get(TTT.RequestKeys[key])){
data = response.get(TTT.RequestKeys[key]).getData();
break;
}
}
// Something bad happened to it
if(null === data){
retryRequest();
return;
}
else{
// Save the actual data to the TTT.List object
current_list.list = data.asArray();
// Save the total number of items in the list
current_list.total = data.getTotalSize();
// Draw the list
TTT.Lists.draw();
}
}
else{
// If there was a permission issue
if(data.getErrorCode() ===
opensocial.ResponseItem.Error.UNAUTHORIZED){
var reason = "To set a custom background for the game board!";
opensocial.requestPermission(
38
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
[MyOpenSpace.Permission.VIEWER_ACCESS_TO_PUBLIC_VIDEOS_PHOTOS],
reason,
TTT.Lists.permCallback);
}
// If there was an error and there are retries left, go for it
else if(current_list.retries > 0){
retryRequest();
return;
}
// Out of retries ...
else{
log("Oops, there was an error! Try refreshing the page.");
}
}
};
The callback checks for errors in the request and handles any retry attempts. Each list
maintains its own retry count, and a failed request is retried the specified number of times.
If there was no error, the response is looped through in an attempt to find out what
data it contains.This allows the callback to handle any kind of response. It can currently
handle the friend list responses, and as you’ll see later on, it can also handle the response
for the photo list.
If everything works (and it should), the data is saved to the
TTT.List
object, along
with the total size of the collection for paging purposes, and the filtered list is drawn.
Since each friend is represented by an
opensocial.Person
object, actually parsing out
the data for each friend is similar to how it was done in Chapter 2. For details, refer to that
chapter, or for a complete code reference for the function
TTT.Lists.draw()
, check the
Chapter 3 sample code found here: />browse/#svn/trunk/chapter3.
Note
You can get only the basic person fields for friends; you can’t get extended data. Basic
person fields are the friend’s ID, display name, thumbnail URL, and Profile URL.
Fetching Media
Media includes a user’s albums, photos, and videos. Dealing with media items is very
similar to the other requests we’ve covered so far, including how they’re fetched, how
you page through a list, and how the response is parsed.
Photos
You can fetch all of the photos your user has uploaded to his or her MySpace Profile,
provided the user grants your app proper permissions. Users can limit permissions, but
we’ll explore how to deal with that later in the permissions section of this chapter. By
default, though, you should have access to all of a user’s public photos. Photos are
Fetching Media
39
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
defined by the
MyOpenSpace.Photo
object, which contains the fields shown in
Table 3.2.These fields are accessed in the same way as for a
Person
, for example,
photo.getField(MyOpenSpace.Photo.Field.CAPTION)
.
Let’s take a look at the function signature that’s used to fetch photos.You’ll notice
that it’s slightly different from how we fetch people:
MyOpenSpace.DataRequest.newFetchPhotosRequest = function(id, opt_params)
id
is a string used to identify who owns the photos.The value can be either
opensocial.IdSpec.PersonId.VIEWER
or
opensocial.IdSpec.PersonId.OWNER
.
opt_params
is an object that specifies optional parameters. In this case only the
paging parameters
opensocial.DataRequest.PeopleRequestFields.FIRST
and
opensocial.DataRequest.PeopleRequestFields.MAX
are allowed.
The reason the function signature is in a different format from the other request
functions is that it is a MySpace-specific extension.The OpenSocial spec defines ways
for containers to extend the core functionality of the OpenSocial spec. In this case
MySpace has added several new endpoints. Because it’s an extension, the function exists
in the
MyOpenSpace
namespace and not the
opensocial
namespace.
In our Tic-Tac-Toe app we fetch the list of photos for the user and allow the user to select
one. That photo then becomes the background for the Tic-Tac-Toe game board. Let’s take a
look at a function that wraps
MyOpenSpace.DataRequest.newFetchPhotosRequest
:
function fetchPhotosList(first, max, callback){
// Add some paging parameters
var params = {};
params[opensocial.DataRequest.PeopleRequestFields.FIRST] = first;
params[opensocial.DataRequest.PeopleRequestFields.MAX] = max;
// Create the DataRequest object
var request = opensocial.newDataRequest();
// Add the request
request.add(MyOpenSpace.DataRequest.newFetchPhotosRequest(
opensocial.IdSpec.PersonId.VIEWER, params),
TTT.RequestKeys.VIEWER_PHOTOS);
// Send it off
request.send(callback);
}
Table 3.2 Fields for the MyOpenSpace.Photo Object
Field Description
PHOTO_ID
The ID number—a photo’s unique identifier
PHOTO_URI
The RESTful API URI that corresponds to this photo
IMAGE_URI
The URL of the photo, which can be used to output the photo to the UI
CAPTION
The photo’s caption
40
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Figure 3.2
Screen shot of a successful photo request.
We set some paging parameters, create the
opensocial.DataRequest
object, and
send off the request.You’ll notice the other big difference here, besides the namespace
change, of executing one of the MySpace extensions.Typically the fetch request, such as
newFetchPeopleRequest
, is called via an instance of an
opensocial.DataRequest
object. However, when using this MySpace extension, we call it statically from the
MyOpenSpace.DataRequest
namespace.You can compare and contrast this function
with the
fetchFriendsList
function to see the slight differences.This code can be
seen in action in Figure 3.2.
Albums and Videos
The pattern for fetching albums and videos is actually the same as it is for fetching
photos. So, if you know how to request photos, you know how to fetch albums and
videos.
Obviously, the fields and objects differ depending on what you’re fetching, but the
basic structure remains the same.That said, we’ve included the fields and function
signatures here as a reference for you.
Albums
Albums are defined by the
MyOpenSpace.Album
object, which contains the fields
outlined in Table 3.3.
Fetching Media
41
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
The function signature is as follows:
MyOpenSpace.DataRequest.newFetchAlbumsRequest = function(id, opt_params)
id
is a string used to identify who owns the albums.The value can be either
opensocial.IdSpec.PersonId.VIEWER
or
opensocial.IdSpec.PersonId.OWNER
.
opt_params
is an object map that specifies optional parameters. In this case only the
paging parameters are allowed:
opensocial.DataRequest.PeopleRequestFields.
FIRST
and
opensocial.DataRequest.PeopleRequestFields.MAX
.
Videos
Videos are defined by the
MyOpenSpace.Video
object, which contains the fields out-
lined in Table 3.4.
The function signature is as follows:
MyOpenSpace.DataRequest.newFetchVideosRequest = function(id, opt_params)
id
is a string used to identify who owns the videos.The value can be either
opensocial.IdSpec.PersonId.VIEWER
or
opensocial.IdSpec.PersonId.OWNER
.
opt_params
is an object map that specifies optional parameters. In this case, only the
paging parameters are allowed:
opensocial.DataRequest.PeopleRequestFields.
FIRST
and
opensocial.DataRequest.PeopleRequestFields.MAX
.
Since the implementation of both the video and album endpoints is so similar to that
of photos, which we’ve already discussed, we leave it to you to experiment with these as
you wish.
Table 3.3 Fields for the
MyOpenSpace.Album
Object
Field Description
ALBUM_ID
The ID number—an album’s unique identifier
ALBUM_URI
The value (RESTful URI) that the API recognizes
TITLE
The album’s title
LOCATION
The geographic location where the album’s photographs were taken
DEFAULT_IMAGE
A URL that points to the album’s default image
PRIVACY
A string indicating the album’s privacy settings; set to either
“Private” or “Public”
PHOTO_COUNT
An integer indicating the number of photos in an album
PHOTOS_URI
The value (RESTful URI) for accessing the photos within the
album
42
Chapter 3 Getting Additional MySpace Data
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
ptg
Using opensocial.requestPermission and
opensocial.hasPermission to Check a User’s
Permission Settings
Permission settings are applied to both data and actions. A user can specify permissions on
a per-app basis, but there are a couple of global permission settings that you’ll need to
either work with or work around (see Chapter 2, Getting Basic MySpace Data, for details).
In our Tic-Tac-Toe app we display a list of the user’s photos to the user. But public
and private photos each have their own permission setting, so we should first check to
see if we have permission before we send out the request. In our app we check whether
we at least have access to the user’s public photos:
function setBackgroundClicked(){
// Create a permission object
var perm = MyOpenSpace.Permission.VIEWER_ACCESS_TO_PUBLIC_VIDEOS_PHOTOS;
// Can we get the photos?
if(opensocial.hasPermission(perm)){
// Yep
fetchPhotos(TTT.ListTypes.SET_BACKGROUND);
}
Table 3.4 Fields for the MyOpenSpace.Video Object
Field Description
VIDEO_ID
The ID number—a video’s unique identifier
VIDEO_URI
The value (RESTful URI) that the API recognizes
TITLE
The video’s title
DATE_CREATED
The date when the video was created
LAST_UPDATE
The date when the video was last updated
MEDIA_TYPE
An integer indicating the media type of the video
DESCRIPTION
A description of the video
THUMB_URL
A URL pointing to the thumbnail image associated with the video
MEDIA_STATUS
The current status of the video
RUN_TIME
The run time, or length, of the video
TOTAL_VIEWS
The total number of views a video has received
TOTAL_COMMENTS
An integer indicating the number of comments the video has
received
TOTAL_RATING
An integer representing the video’s overall rating
TOTAL_VOTES
An integer representing the total number of votes the video has
received
COUNTRY
A string indicating the video’s country of origin; typically used to
identify culture, not geographic location
LANGUAGE
A string indicating the video’s language
Using opensocial.requestPermission and opensocial.hasPermission
43
From the Library of Lee Bogdanoff
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.