Saving your data on PMDS

The holidays are over and now it’s time to progress! So, with that in mind I dedicated my work yesterday to understand how to apply persistent data in OpenSocial apps. Previously, I spent some time searching how to store data into the reserved space orkut sets aside for individual apps in order to allow users to store and retrieve data. I found a few methods that I thought I should attempt to implement into my app PMDS (Personal Metagenome Data Storage). In doing so I ran into a few very confusing problems, but nonetheless I found solutions and PMDS can now save data into the app itself. With this new understanding we have opened up the possibilities of displaying, sharing, storing, and updating information and data with ease. Now the implementation isn’t exactly how I want it to be; right now it only saves the titles of the objects that are stored in our server and then displays them in a list, but what’s important is that we can do whatever we want with whatever data we want to save. If you’re interested in the JavaScript code I have for the app, click here or the Read More.

 

To begin, I’d like to explain a little bit about the OpenSocial API and how it provides methods for retrieving a viewer’s data (a viewer being the person who is viewing the app on their computer).

Each user’s account is supplied with data fields that they can or are required to fill in to have an account. Examples of these are a name, gender, a profile picture, hobbies, activities, etc. Users are also supplied with data storage for each application they have added to their account. OpenSocial allows developers to use this storage if the app needs or wants to save persistent data. The API provides request methods to access this storage or profile information if the developer decides to use, such as accessing the names of the viewer’s friends or using their profile pictures.

The method I am using allows the user to save the titles of the data they have stored into the server. Whenever the user clicks the Save button, PMDS sends a request to retrieve an array containing the previously saved titles, adds the new title to the end of that array, then sends a request to store the array back into the PMDS storage. Whenever the user clicks the Load button, PMDS sends a similar request to retrieve the stored array and then displays a list of the saved titles. This can be changed to better suit the needs of those that are using this, such as supplying a drop down menu or something more useful, but it’s good that the app is supplying us with a visual list we can see.

Here is some of the code I used to implement the save and load features:

allresults = [];   //array used to populate with titles to be saved
var req = opensocial.newDataRequest();
var idspec = opensocial.newIdSpec({"userId" : "VIEWER", "groupId" : "SELF" });
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "viewer");
req.add(req.newFetchPersonAppDataRequest(idspec, "savedResults"), "viewer_data");
req.send(function(response) { ... });

 

This is the first part of the save implementation. What is happening here is that a request is being created and sent to retrieve the array that contains the previously saved titles. The highlighted portion is the “key” that must be specified so the app knows which data to search for. This is important because you can store different data into the app and the key is what is used to differentiate which data is being searched for. The request is sent with an inline function passed through. This function isn’t shown but it basically does some error checking and then checks to see if there were any previous saved titles to add the new title to. Now, all of this is essentially the same code I used for the load feature of PMDS. The only difference is the code that is in the request-inline function. In the load section a list is displayed if there are any previously saved titles.

 

allresults.push(mTitle);
req = opensocial.newDataRequest();
req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER), "savedResults", gadgets.json.stringify(allresults)), "set_data");
req.send(saveResultsResponse);

This is the second part of the save implementation. This is the request to save the allresults array into PMDS. Again, we must supply the same key “savedResults” so we can continue to overwrite the previous data. The request is sent with a callback function passed through. This function isn’t shown but does error checking to be sure that the data was saved successfully.

 

Here is my complete load implementation. I decided to show the entire thing incase anyone wanted to see a full example of how it works.

function loadResults() {

var req = opensocial.newDataRequest();
var idspec = opensocial.newIdSpec({"userId" : "VIEWER", "groupId" : "SELF"});

req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), "viewer");        
req.add(req.newFetchPersonAppDataRequest(idspec, "savedResults"), "viewer_data");    
req.send(loadResultsResponse);
}

/**
* Callback function for loadResults()
*/
function loadResultsResponse(response) {

if( response.hadError() )
errors_div.innerHTML = "DEV-ERROR: there was an error with the response";

else if( response.get("viewer_data").hadError() )
errors_div.innerHTML = "DEV-ERROR: there was an error retrieving the data";

else {
var html = [];
var viewer = response.get("viewer").getData();
var data = response.get("viewer_data").getData();
var results = data[viewer.getId()];

if( viewer && results ) {
var previous = gadgets.util.unescapeString(results["savedResults"]);
previous = gadgets.json.parse(previous);
var count = 0;
for( obj in previous) {
count++;
html.push(count + ": " + previous[obj] + "<br />");
}
savedresults_div.innerHTML = html.join("");
}
else if( !viewer )
errors_div.innerHTML = "DEV-ERROR: viewer undefined, results undefined";
else
errors_div.innerHTML = "Sorry, there are no saved results.";
}
}

Note: the variables with “_div” at the end of them are html objects that are located in the xml portion of the app.

Anyone can find out more about persistent data in these two websites where I obtained most of my information from:

http://code.google.com/apis/opensocial/docs/0.8/devguide.html

http://wiki.opensocial.org/index.php?title=The_Persistence_API