MySpace Specific Extensions on OpenSocial
You may be wondering where OpenSocial ends and MySpace begins. In a nutshell: if it's in the "OpenSocial" namespace, it's OpenSocial. If it's in the "MyOpenSpace" namespace, it's MySpace. If you look through the MyOpenSpace JavaScript, you'll see plenty of "extra" functionality, such as Photo Albums (a MySpace-specific extension). When should you try to access that functionality? And how?
Let's step back a second and look at the way the JavaScript is structured. OpenSocial is a JavaScript API encompassed in a file called "opensocialreference.js". That file provides you with an interface to program your app against. On the other end, MySpace is implemented in a JavaScript file called "MyOpenSpace.js". "MyOpenSpace.js" is dependent on "opensocialreference.js". The latter provides MyOpenSpace with a set of back-end hooks so we can inject our site-specific code behind OpenSocial. This is done through an inheritance mechanism. For example, OpenSocial defines a Person object thusly:
code snippet 10 : MySpace Extensions: OpenSocial base Person implementation
opensocial.Person = function(opt_params, opt_isOwner, opt_isViewer) {
this.fields_ = opt_params || {};
this.isOwner_ = opt_isOwner;
this.isViewer_ = opt_isViewer;
};
opensocial.Person.Field = {
ID : 'id',
NAME : 'name',
THUMBNAIL_URL : 'thumbnailUrl',
PROFILE_URL : 'profileUrl'//,
};
opensocial.Person.prototype.getId = function() {
return this.getField(opensocial.Person.Field.ID);
};
opensocial.Person.prototype.getDisplayName = function() {
return this.getField(opensocial.Person.Field.NAME);
};
opensocial.Person.prototype.getField = function(key) {
return this.fields_[key];
};
opensocial.Person.prototype.isViewer = function() {
return !!this.isViewer_;
};
opensocial.Person.prototype.isOwner = function() {
return !!this.isOwner_;
};
The above is the Person object you code against (examples of how to do this will come). MySpace then takes that stubbed out Person object and inherits from it, resulting in code that looks like this:
code snippet 11 : MySpace Extensions: MySpace Person object definition
MyOpenSpace.Person = function(opt_params, opt_isOwner, opt_isViewer) {
myOsTrace("MyOpenSpace.Person()");
opensocial.Person.call(this, opt_params, opt_isOwner, opt_isViewer);
this["_setField"] = function(key,val) { this.fields_[key] = val; }; //TODO: find a better way to extend
this._type = 0;
}
MyOpenSpace.Person.Field = {
CITY:"CITY",
REGION:"REGION",
POSTALCODE:"POSTALCODE",
COUNTRY:"COUNTRY",
HOMETOWN:"HOMETOWN",
AGE:"AGE",
GENDER:"GENDER",
ABOUT:"ABOUT",
CULTURE:"CULTURE",
MARITAL_STATUS:"MARITAL_STATUS",
INTERESTS:"INTERESTS",
MUSIC:"MUSIC",
MOVIES:"MOVIES",
TELEVISION:"TELEVISION",
BOOKS:"BOOKS",
HEROES:"HEROES",
HEADLINE:"HEADLINE",
OCCUPATION:"OCCUPATION",
ZODIAC_SIGN:"ZODIAC_SIGN",
MOOD:"MOOD",
STATUS:"STATUS",
DESIRE_TO_MEET:"DESIRE_TO_MEET"
}
MyOpenSpace.Person.inherits(opensocial.Person);
As you can see, the MySpace Person object inherits the functionality and attributes from the OpenSocial Person object, and also adds its own. Your code can access those fields, even though it's holding a reference to the opensocial.Person. You do this by appending fields to a "params" object passed into the DataRequest:
code snippet 12 : MySpace Extensions: Requesting MySpace-specifiec properties
function init() {
MYOS_TRACE = true;
var os = opensocial.Container.get();
var dataReqObj = os.newDataRequest();
var param = {};
param[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] =
[opensocial.Person.Field.ID,
MyOpenSpace.Person.Field.HEROES,
MyOpenSpace.Person.Field.MOVIES];
var viewerReq = os.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER,param);
dataReqObj.add(viewerReq);
dataReqObj.send(dataLoadCallback);
}
Once you have issued a request for particular extended fields, you can deal with the response with the below code:
code snippet 13 : MySpace Extensions: Grabbing MySpace-specific properties off the Viewer
function dataLoadCallback(data) {
var viewer = data.get(opensocial.DataRequest.PersonId.VIEWER).getData();
heading = 'Hello, ' + viewer.getDisplayName();
var thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
var profile = viewer.getField(opensocial.Person.Field.PROFILE_URL);
var heroes = viewer.getField(MyOpenSpace.Person.Field.HEROES);
var movies = viewer.getField(MyOpenSpace.Person.Field.MOVIES);
alert(heroes);
alert(movies);
}
In the above code you can see that we're double dipping between the OpenSocial and MyOpenSpace namespaces to get both OpenSocial standard and MySpace specific properties off an object.
Putting the above together into a cut-and-paste app:
working app 4 : Getting MySpace Specific Profile Fields
<div id='main'></div>
<script type="text/javascript">
function init() {
MYOS_TRACE = true;
var os = opensocial.Container.get();
var dataReqObj = os.newDataRequest();
var param = {};
param[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.ID, MyOpenSpace.Person.Field.HEROES, MyOpenSpace.Person.Field.MOVIES];
var viewerReq = os.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER,param);
dataReqObj.add(viewerReq);
dataReqObj.send(dataLoadCallback);
}
function dataLoadCallback(data) {
var viewer = data.get(opensocial.DataRequest.PersonId.VIEWER).getData();
heading = 'Hello, ' + viewer.getDisplayName();
var thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
var profile = viewer.getField(opensocial.Person.Field.PROFILE_URL);
var heroes = viewer.getField(MyOpenSpace.Person.Field.HEROES);
var movies = viewer.getField(MyOpenSpace.Person.Field.MOVIES);
document.getElementById('main').innerHTML += heading + '<br> <img src=' + thumb + '> <br> <a href=' + profile + '> <br> ' + heroes + '<br> ' + movies + '<br>';
}
init();
</script>
The extensions don't end with special properties. You'll also see special RequestItem objects that represent MySpace specific objects that can be fetched through the MySpace API. These special RequestItem objects go through the standard DataRequest pipeline, so you can take advantage of batching.
code snippet 14 : MySpace Extensions: Grabbing special objects off the server
<div id='main'></div>
<script type="text/javascript">
function init(){
var dataRequest = opensocial.newDataRequest();
var param = {};
//Create a request for the owner's albums
var albumRequest = dataRequest.newFetchAlbumsRequest(opensocial.DataRequest.PersonId.OWNER,param);
//Add the request for processing.
dataRequest.add(albumRequest);
//Send the request, passing in a callback.
dataRequest.send(response);
}
function response(data)
{
var albums = data.get(MyOpenSpace.Group.OWNER_ALBUMS).getData();
albums.each(
function(album) {
var albumId = album.getField(opensocial.Album.Field.ID);
var albumTitle = album.getField(opensocial.Album.Field.TITLE);
var albumImage = album.getField(opensocial.Album.Field.DEFAULT_IMAGE);
document.getElementById('main').innerHTML += '<br> album id' + albumID + '<br> album title=' + albumTitle + '<br><img src=' + albumImage + '><br>';
}
);
}
init();
</script>
Meditate on that code for a bit and notice how the namespacing works. You can see that everything is organized in such a way as to be discoverable. In the same way that OpenSocial has the "Group" object to determine what types of bulk requests you can make, MyOpenSpace has a "Group" object that extends on it and adds Photos, Albums, etc.
Now that you've done your homework is time to PLAY! Check out our Example apps for your pasting pleasure!!