Skip ahead if you just want to retrieve data >>>
As of today, Opensocial is not functional in Internet Explorer, so the following assumes you are running Firefox on Orkut's container (or another FULLY FUNCTIONAL container).
The Data Relationship:
The image above depicts the relationship between a Person, an App, and the available data relationship types (excluding Global). Note that Person App Data relates to a Person and an App, not a Person and an App Instance. In fact, any running instance of
an app should have access to the exact same appData for each Person in a given container. App Data itself (instance or not) is only available to the application that stored it, and unavailable to any other applications (via the Javascript API).
Person App Data can be STORED with relation to (1) person (currently):
The data can be RETRIEVED with relation to (3) groups:
Currently UPDATING app data for 'OWNER' will result in an internal server error.
Also, in the future, you will be able to update person app data by using an ID for an individual associated with one of: 'OWNER' , 'VIEWER' , 'OWNER_FRIENDS' , 'VIEWER_FRIENDS'. Though the api is not supporting this right yet.
What uses does this have?
Well generally speaking, if you have your application store data for each individual 'VIEWER', you can then have the application read information for each application's 'OWNER_FRIENDS'. If the benefits aren't completely obvious, consider this:
A game application wishes to store high scores for each individual player, and also show each player what the high scores were for the 'OWNER_FRIENDS'. To accomplish this, the game would store the data under 'VIEWER' and retrieve it via 'OWNER_FRIENDS'.
Note that a list of high scores is better suited for
appInstanceData, or globalAppData which are both topics for another day.
How it's done:
Updating personAppData is much simpler than retrieving it. To begin, we need to create an instance of opensocial.newDataRequest().
I've created an Object called personAppData, and given it (1) variable to hold an opensocial.DataRequest object, which I'll instantiate within a function called init();
var personAppData = {
reqObj:null
,init:function(){
this.reqObj = opensocial.newDataRequest( )
}
}
Now I'm ready to store data. I want to create a set() function with (4) arguments:
First, I want to initialize our personAppData object if it isn't already.
Then I want to use the opensocial.DataRequest.add() function to pass my request to the opensocial.DataRequest before I send() it.
var personAppData = {
reqObj:null
,init:function(){
this.reqObj = opensocial.newDataRequest( )
}
,set:function( callBack , person , key , data ){
if( ! this.reqObj ) this.init();
this.reqObj.add( this.reqObj.newUpdatePersonAppDataRequest( person , key , data ) , 'updatedData' );
}
}
I'm going to need to store a reference to my custom personAppData Object (the object I'm working on) so that I can reference the correct function to call when the send process has completed. I'll also send in my custom callBack so that it get's passed along to the next method.
To store a reference to the current Object, I use the line: var _self = this;. The reason is that when working with callbacks, the keyword 'this' often does not have the same reference as was initially intended. By storing my 'this' reference in another variable, I'm ensured that it will always point to 'this' Object.
Notice that within the reqObj.send function, I've defined my own function with an argument called 'ret'. This is the object that will contain my data, it is returned from the send function, I'm passing that to the sendReturn function along with my custom callBack.
var personAppData = {
reqObj:null
,init:function(){
this.reqObj = opensocial.newDataRequest( )
}
,set:function( callBack , person , key , data ){
if( ! this.reqObj ) this.init();
this.reqObj.add( this.reqObj.newUpdatePersonAppDataRequest( person , key , data ) , 'updatedData' );
var _self = this;
this.reqObj.send( function( ret ){
_self.sendReturn( ret , callBack );
});
}
}
Now I can handle the update response that is triggered by the send function. I want to set up the sendReturn() function with (2) arguments:
I'll also set up a log() function to output
some sort of status code. That way the status code can be easily redirected to another method besides alert().
Within the sendReturn function, all I want to do is check to see that the data update did not return an error, then fire the custom callBack function to finish the process. I can safely assume that the ret.get('updatedData') will exist and will have a .hadError() function.
var personAppData = {
reqObj:null
,init:function(){
this.reqObj = opensocial.newDataRequest( )
}
,set:function( callBack , person , key , data ){
if( ! this.reqObj ) this.init();
this.reqObj.add( this.reqObj.newUpdatePersonAppDataRequest( person , key , data ) , 'updatedData' );
var _self = this;
this.reqObj.send( function( ret ){
_self.sendReturn( ret , callBack );
});
}
,sendReturn:function( ret , callBack ){
if( ret.get( 'updatedData' ).hadError() ){
this.log( 'An error occured during the update.' );
return; // terminate the function
} // else
callBack();
return;
}
,log:function( str ){
alert( str );
}
}
Great! Now we can easily update Person App Data by calling a simple function.
Below I've made the call to update Person App Data for the 'VIEWER'. I've given the data the key:'myData' (which I'll use to retrieve it) and the value:'This is the data value.' When the process is done, the callBack will fire and I'll get an alert message saying: 'Data update complete.'.
personAppData.set( function(){
alert('Data update complete.');
}
,'VIEWER'
,'myData'
,'This is the data value.'
);
Very nice, now we can do updates without having to call multiple methods. Storing the data is the easy part, now I'll show you how to retrieve it >>>.