Home Our Apps Contact Articles
Saturday, March 1, 2008

Temporary user preferences for Orkut.

This is a basic getter/setter object for Orkut user preferences using appData. Please feel free to use it.

At the time of this writing, user preferences don't function on Orkut in the same way they do on iGoogle. Also, gadgets.prefs still has a few kinks that need ironing out.

I put together this basic preference getter/setter object for use in some iWiddit applications. It uses appData requests to store and retrieve OWNER data (essentially preferences). You all are more than welcome to use all or part of this code in your own apps.

Note that this functionality should be replaced by gadgets.prefs once they get the kinks ironed out.

How to use it: You'll want to initialize the object first, and you'll likely want to send in a callback method and default data to make sure that subsequent method calls will actually return something other than null.

Note that the iw_prefs.init method callback argument should be used to delay your script until this data is available, that is, the data won't be available until the init method has completed. If you try to retrieve data before the init method completes (using .get or .getAll) you will retrieve either your default values, or a null value if you didn't set defaults.

The get and getAll methods are fairly straight forward. The only caveat is that the init method must have completed prior to calling the get method. To get a user preference with a specific key, simply call iw_prefs.get( key ) and the correct value will be returned.

Note that the init method has already populated this data into the iw_prefs object, so any calls to iw_prefs.get( x ) will NOT fire an AJAX request. This means you don't have to feel bad about using multiple gets sequentially.

Alternatively, if you simply wish to itterate through the appData for this OWNER, you can call iw_prefs.getAll() and you'll get back a JSON object containing matching key/value pairs. To access the data, simply use returned_data[key]. Iteration can be accomplished by using a for.. in construct.

Setting preferences is also fairly straight forward. Using the success_callback and error_callback you should be able to split your application flow on this method depending on success/failure. Also, the keys argument is an object, so you can send a JSON key/value map straight into here and it will update ALL of the data contained. An example JSON key/value map looks like this:

{
"preference_1": "Value_1",
"preference_2": "Value_2",
"preference_3": "Value_3"    
    }

Note that after the data is updated, any subsequent calls to iw_prefs.get or iw_prefs.getAll will return the correct updated data. You don't have to call the iw_prefs.init() method again.

The Methods: The iw_prefs object currently contains (4) public methods:

  1. iw_prefs.init( success_callback_, default_data_ ): Initializes the object and populates current values. This method should be called before any other.
    • success_callback_: (Function) An optional function to call when the initialization process is complete.
    • default_data_: (Object) A JSON object containing default key/value pairs to be used in the event that the preference doesn't exist. (eg fresh install)
  2. iw_prefs.get( key ): Gets a preference value
    • key: (String) The key of the preference to fetch.
  3. iw_prefs.getAll( ): Gets all appData for the OWNER as a JSON object containing key/value pairs.
  4. iw_prefs.set( keys, success_callback, error_callback ): Attempts to set a group of preferences
    • keys: (Object) A JSON object containing key/value pairs to set.
    • success_callback (Function) The method to call if the data is set correctly.
    • error_callback (Function) The method to call if an error occurs.

Finally... the code:

/*

 Copyright 2008 -- www.iWiddit.com 
 
 Licensed under the Apache License, Version 2.0 (the "License"); 
 you may not use this file except in compliance with the License. 
 You may obtain a copy of the License at 
 
    http://www.apache.org/licenses/LICENSE-2.0 
 
 Unless required by applicable law or agreed to in writing, 
 software distributed under the License is distributed on an "AS IS" BASIS, 
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 See the License for the specific language governing permissions and 
 limitations under the License.

*/
var iw_prefs = {
            // storage for owner app data values
            preference_data:null
            // default values sent to init function
            ,default_data:null
                        
            /***** Public Methods
            *
            *   Initialize the object, set default values
            *   @param :: call_back_ :: optional :: the function to call when the init process has completed
            *   @param :: default_data_ :: optional :: the default data object
            *                this is the data that is returned in case there are no user-specific values for OWNER
            *                e.g. fresh install
            *   @public
            */
            ,init:function( call_back_, default_data_ ){
                // make sure the call_back is actually a function
                var call_back = call_back_ || function(){};
                // store default data
                this.default_data = default_data_ || {};
                // initialize preference_data to default data
                this.preference_data = this.default_data; 
                // instantiate a DataRequest object
                var reqObj = opensocial.newDataRequest();
                // get the opensocial OWNER identifier
                var os_owner = opensocial.DataRequest.PersonId.OWNER;
                // queue a request for owner preferences
                reqObj.add( reqObj.newFetchPersonAppDataRequest( os_owner, '*' ), 'owner_prefs' );
                // queue a request for owner Person object
                reqObj.add( reqObj.newFetchPersonRequest( os_owner ), 'app_owner' );
                // store reference to 'this'
                var _self = this;
                // send the request
                reqObj.send( 
                    function( dat ){ 
                        _self.populate( dat, call_back ); 
                    } 
                );  
            }
            /*
            *   Gets a preference value by key
            *   @param :: key :: the string preference key
            *   @returns :: the associated value, or default value if a preference doesn't exist
            *   @public
            */
            ,get:function( key ){
                // make sure the preference object isn't null before checking properties
                if( this.preference_data && this.preference_data[ key ] ) return this.preference_data[key];
                // make sure the default data object isn't null before checking properties
                if( this.default_data && this.default_data[ key ] ) return this.default_data[key];
                // this case shouldn't occur
                return null;
            }
            /*
            *   Gets the entire preference object ( all appData for the OWNER )
            *   @returns :: the entire appData object for the OWNER
            *   @public
            */            
            ,getAll:function(){
                return this.preference_data || this.default_data || {};    
            }
            /*
            *   Sets a preference or list of preferences as appData for the app OWNER only if the current VIEWER == OWNER
            *   @param :: keys :: an object conaining the key/value pairs.
                        Example :: {
                                        "var1": "value1",
                                        "var1": "value2"
                                    }
            *   @param :: success__ :: optional :: the callback method to fire upon success
            *   @param :: err_ :: optional :: the callback method to fire upon error
            *   @public
            */                          
            ,set:function( keys, success_, err_ ){
               // make sure callbacks are functions
               success = success_ || function(){};
               err = err_ || function(){};
               // get the opensocial VIEWER identifier
               var os_viewer = opensocial.DataRequest.PersonId.VIEWER;
               // instantiate a new data request
               var reqObj = opensocial.newDataRequest(); 
               // check for viewer object permissions
               if( !opensocial.hasPermission( opensocial.Permission.VIEWER ) ) err();
               // queue a request to retrieve the viewer object
               reqObj.add( reqObj.newFetchPersonRequest( os_viewer ), 'current_viewer' );
               // store reference to 'this'
               var _self = this;
               // send the request
               reqObj.send( 
                    function( dat ){ 
                        _self.verify( dat, keys, success, err ); 
                    }
               );
            }
            /***** Private Methods
            *
            *   Handles the returned data from the init method, stores this data for easy retrieval later on
            *   @param :: data_response :: the data response from the request
            *   @param :: call_back :: the callback function to be fired when the init process is complete
            *   @private
            */
            ,populate:function( data_response, call_back ){
                // extract owner person to get object or null on failure
                var owner_person = this.extract( data_response, 'app_owner' );
                // extract preference_data to get object or null on failure
                var preference_data = this.extract( data_response, 'owner_prefs' );
                // make sure we have both owner and the preference data
                if( !owner_person || !preference_data ) return;
                // get person specific preferences
                preference_data = preference_data[ owner_person.getId() ];
                // count the number of preferences
                var count = 0;
                for( var x in preference_data ){ 
                    count++; 
                }
                // use default data if preferences returned an empty object
                this.preference_data = count > 0 ? preference_data : this.default_data;
                // fire the callback method
                call_back();
            }           
            /*
            *   This is a movable method that checks a response object for errors and handles unsupported issues.
            *   @param :: response :: the response object
            *   @param :: expected_item_key :: the key of the data that is being requested
            *   @returns :: the data object, or null on failure
            *   @private
            */           
            ,extract: function( response, expected_item_key ){
                // get outer response object
                var c_resp = response.get( expected_item_key );
                // check for overall response error
                if( typeof( c_resp.hadError ) == 'function' && c_resp.hadError() ) return;
                // get responseItem object from the returned data
                var rData = c_resp.getData();
                // check for item specific error
                if( typeof( rData.hadError ) == 'function' && rData.hadError() ) return;
                // finally, return the data object
                return rData;		                        
            }
            /*
            *   Verifies that VIEWER == OWNER, then proceeds to update the appData preference for the OWNER
            *   @param :: data_response :: the data response containg the viewer object
            *   @param :: keys :: the keys object from the set method
            *   @param :: success :: the callback method to fire upon success
            *   @param :: err :: the callback method to fire upon error
            *   @returns :: null
            *   @private
            */              
            ,verify:function( data_response, keys, success, err ){
               // extract viewer from the data_response
               var viewer_person = this.extract( data_response, 'current_viewer' );
               // make sure viewer == owner
               if( !viewer_person || !viewer_person.isOwner() ){ 
                        err();
                        return;
               }
               // create a new data request
               var reqObj = opensocial.newDataRequest();
               // get the opensocial VIEWER identifier
               var os_viewer = opensocial.DataRequest.PersonId.VIEWER;
               // itterate through the keys object and add the data update requests for VIEWER
               // also update the current local preference_data object
               for( var x in keys ){
                     reqObj.add( reqObj.newUpdatePersonAppDataRequest( os_viewer, x, keys[x] ) );
                     this.preference_data[x] = keys[x];
               }
               // send the request
               reqObj.send( success );
            }
                                 
                }


[ Page Top ](c)2008 iWiddit.com - Privacy Policy - Feedback - SiteMap

iWiddit Logo iWiddit Opensocial Developers