Previously in this tutorial, we created an Object (shown below) for updating Instance App Data by calling a single method.
If you like, you can jump ahead and just download the entire instanceAppData Object.
var instanceAppData = {
reqObj:null
,init:function(){
if( !this.reqObj ) this.reqObj = opensocial.newDataRequest();
}
,set:function( data, key, callBack, error ){
this.init();
try{
JSON.stringify( data );
}catch(e){
error(e);
return;
}
this.reqObj.add( this.reqObj.newUpdateInstanceAppDataRequest( key , data ) , 'update' );
var _self = this;
this.reqObj.send( function( ret ){
_self.setRet( callBack, error, ret );
});
}
,setRet:function( callBack, error, ret ){
if( ret.hadError() || ret.get('update').hadError() ){
error( ret.getError() );
return;
}
callBack();
}
}
We then set some data using the calls below.
// setting some data, then setting some more data
instanceAppData.set(
'This is myData.'
,'myData'
,setMoreData // callback function
,function(e){ alert(e); }
);
function setMoreData(){
instanceAppData.set(
['This is a data array - first value.', 'This is a data array - second value.']
,'myData2'
,getAllData // callback function
,function(e){ alert(e); }
);
}
Retrieving the Data The getter method we want to write will be called get(), and take (3) arguments:
Inside of the get function we need to first initialize our object if it hasn't been already. We just call the init() method to do this.
After that, all we need to do is add() a newFetchInstanceAppDataRequest() to our DataRequest Object and then
send() it. We simply need to pass along the keys argument, since it's already in the correct format.
We need to get a reference to our Object (to 'this') so we can pass function references around without worrying about 'this' changing. We'll do this by using the line: var _self = this;.
The send() function expects a callBack as an argument. So we'll send in a function and have pass along the value returned from the send() function. We'll send the returned value, along with our custom callBack and error functions, to a getRet() function that we'll create next.
var instanceAppData = {
reqObj:null
,init:function(){
if( !this.reqObj ) this.reqObj = opensocial.newDataRequest();
}
,set:function( data, key, callBack, error ){
this.init();
try{
JSON.stringify( data );
}catch(e){
error(e);
return;
}
this.reqObj.add( this.reqObj.newUpdateInstanceAppDataRequest( key , data ) , 'update' );
var _self = this;
this.reqObj.send( function( ret ){
_self.setRet( callBack, error, ret );
});
}
,setRet:function( callBack, error, ret ){
if( ret.hadError() || ret.get('update').hadError() ){
error( ret.getError() );
return;
}
callBack();
}
,get:function( keys, callBack, error ){
this.init();
this.reqObj.add( this.reqObj.newFetchInstanceAppDataRequest( keys ), 'myData' );
var _self = this;
this.reqObj.send( function( ret ){
_self.getRet( callBack, error, ret );
});
}
}
Handling the Returned Data Now we can build a method to handle the returned values. We'll call this method getRet() and give it (4) arguments:
The first thing we'll do is handle any errors that may have occurred. If something went wrong, we'll fire our error method and exit.
var instanceAppData = {
reqObj:null
,init:function(){
if( !this.reqObj ) this.reqObj = opensocial.newDataRequest();
}
,set:function( data, key, callBack, error ){
this.init();
try{
JSON.stringify( data );
}catch(e){
error(e);
return;
}
this.reqObj.add( this.reqObj.newUpdateInstanceAppDataRequest( key , data ) , 'update' );
var _self = this;
this.reqObj.send( function( ret ){
_self.setRet( callBack, error, ret );
});
}
,setRet:function( callBack, error, ret ){
if( ret.hadError() || ret.get('update').hadError() ){
error( ret.getError() );
return;
}
callBack();
}
,get:function( keys, callBack, error ){
this.init();
this.reqObj.add( this.reqObj.newFetchInstanceAppDataRequest( keys ), 'myData' );
var _self = this;
this.reqObj.send( function( ret ){
_self.getRet( keys, callBack, error, ret );
});
}
,getRet:function( keys, callBack, error, ret ){
if( ret.get('myData').hadError() ){
error( ret.getError() );
return;
}// no error
}
}
When we request the data, it data will come back as a Map <String>:<String> Object. Since we used JSON to stringify Array data before we updated it, we'll need to parse it out (de-stringify it) before we return it.
That way, our returned object will be a Map <String>:<String>||<Array> Object, and will depend on the type of data that was originally updated.
To do this, we'll just use the 'keys' argument to check for and parse corresponding values in the returned data object.
The JSON.parse method will throw an error if we send it a non-JSON string, so we'll wrap that function call in a try/catch to make sure it doesn't stop our function.
By parsing each value, we ensure that any value that was originally an Array, will be returned as an Array. Likewise, if the data was set as a String, it will be returned as a String.
The final step is to fire our callBack function and send in the returned data.
var instanceAppData = {
reqObj:null
,init:function(){
if( !this.reqObj ) this.reqObj = opensocial.newDataRequest();
}
,set:function( data, key, callBack, error ){
this.init();
try{
JSON.stringify( data );
}catch(e){
error(e);
return;
}
this.reqObj.add( this.reqObj.newUpdateInstanceAppDataRequest( key , data ) , 'update' );
var _self = this;
this.reqObj.send( function( ret ){
_self.setRet( callBack, error, ret );
});
}
,setRet:function( callBack, error, ret ){
if( ret.hadError() || ret.get('update').hadError() ){
error( ret.getError() );
return;
}
callBack();
}
,get:function( keys, callBack, error ){
this.init();
this.reqObj.add( this.reqObj.newFetchInstanceAppDataRequest( keys ), 'myData' );
var _self = this;
this.reqObj.send( function( ret ){
_self.getRet( keys, callBack, error, ret );
});
}
,getRet:function( keys, callBack, error, ret ){
if( ret.get('myData').hadError() ){
error( ret.getError() );
return;
}// no error
var myData = ret.get('myData').getData(); // myData is now a Map Object
var retData = {};
if( typeof( keys ) == 'string' ) {
try{
retData[keys] = myData[keys];
}catch(e){
// do nothing...
}
}else{
for( var i = 0; i < keys.length; i++ ){
try{
retData[keys[i]] = JSON.parse( myData[keys[i]] );
}catch(e){
retData[keys[i]] = myData[keys[i]];
}
}
}
callBack( retData );
}
}
Let's take a look at the returned Map object we've created (the one containing our data that will be passed to the callBack function). It should look something like this:
{
myData:'This is myData.'
,myData2:['This is a data array - first value.', 'This is a data array - second value.']
}
As you can see, the data was returned as either an Array or a String depending on what type it was when it was set. To access the values we can use the following calls:
Finishing Up! Pretty simple huh? To finalize, we'll write the method call to get the data, and a function to handle the returned data. See Below:
// getting back data
instanceAppData.get(
['myData', 'myData2'] // keys (This can also be a String)
,handleData // callBack method
,function(e){ alert(e); } // error method
);
function handleData(ret){
// look for myData (Should be a String)
alert( 'myData: '+ret['myData'] );
// look for myData2 (Should be an Array)
var myData2 = ret['myData2'];
for( var i = 0; i < myData2.length; i++ ){
alert( myData2[i] );
}
}
If you like, you can download the entire instanceAppData Object.
Also, if you missed it, check out the first part of this tutorial: updating Instance App Data by calling a single method.