Loading ...
Sorry, an error occurred while loading the content.

Re: [ydn-javascript] Re:DataSource and parseJSONData

Expand Messages
  • Hollywood
    Federico, I did read the documentation. And I did attach to all events and I did do the debugging and it did not perform as I needed it to perform. Obviously
    Message 1 of 8 , Jan 31, 2008
    • 0 Attachment
      Federico, I did read the documentation.  And I did attach to all events and I did do the debugging and it did not perform as I needed it to perform.  Obviously you didn't pay attention to what I actually wrote either. 
       
      As far as the override to parseJSONData, the documentation for the parseJSONData also reads:
       
      * Overridable method parses raw JSON data into a response object.
       
      Don't like my override?  Do not use it.  Someone else may find it useful.  Otherwise, get off your high horse.
       
      ----- Original Message -----
      Sent: Thursday, January 31, 2008 2:43 AM
      Subject: [ydn-javascript] Re:DataSource and parseJSONData

      First line of online documentation reads: "The DataSource Utility
      provides a common configurable interface for other components to fetch
      tabular data from a variety of local or remote sources..."
      Now focus on "tabular data". DataSource is meant to deal with list or
      list of list kind of structures only, that's what resultsList
      identifies, the list structure which makes up main data.
      Those properties you want to bring in, are in fact meta-data, data
      about your main list.
      Later in documentation:
      "responseEvent
      most useful argument is oArgs.response which is the raw response
      (undecoded) as received from the original source. This is useful to
      asynchronously retrieve any extra information (meta-data) contained
      along the main tabular data."
      It turns out you can subscribe to responseEvent and have access to the
      whole json and extract/store any meta-data for further reference.
      You should really read documentation thoroughly and try to understand
      how a component work or even ask before going and completely revamp it.

      Bye,
      Federico

    • Hollywood
      Saytam, That is all well and good. But that is not the issue. The issue is when it gets back to the dataTable. I m not interested in overriding the data
      Message 2 of 8 , Jan 31, 2008
      • 0 Attachment
        Saytam,
         
        That is all well and good.  But that is not the issue.  The issue is when it gets back to the dataTable.  I'm not interested in overriding the data when its in the DataSource, but rather when it gets to the DataTable.
         
        And yes, but there are also two issues with that, its in 2.5.0 and not 2.4.1 which is current, and secondly its still an issue in that its in the DataSource and that the DataSource is sending the DataTable stripped down information.
         
        The server-side pagination/sorting examples I believe is not the correct solution.  To me the DataSource should not be modifying the DataTable.   DataTable should request data via the DataSource, the DataSource should provide that data, and then its up to the DataTable to do with it what it wants.  With the my override to the parseJSONData, instead of defining a doBeforeCallback function on the DataSource to setup the dataTable.set() for the sorting when the data is returned from the server, you can just define a doBeforeLoadData function on the DataTable and have it call the set sorting.  This keeps both operations for the sorting within the scope of the DataTable where it belongs.   The DataSource should know *nothing* about the setting up the DataTable.
         
        Lastly, and while everyone has their own coding style, when I actually took a look at the parseJSONData it from a code standpoint didn't make a whole lot of sense.  There are three conditions and unmodified parseJSONData needs to meet:  a) you must have a valid oRawResponse, b) you must have a responseSchema.resultsList defined, and c) you must have a responseSchema.fields array defined.  If you don't have all three of those then the parseJSONData isn't going to work.   In the code as it stands, there is a check for the oRawResponse and fields, but never the resultsList, so if you pass in a null or empty string you get an error during the jsonList = eval("jsonObj."....) call.  IMO (and yes, its no better or worse than anyone elses, some people not withstanding) you should check for the three conditions up front.  If those three conditions aren't satisfied, return with your error message.   Next step would attempt to parse the oRawResponse to produce your jsonObj.  Since you are in a big if/else condition, doing all the (!jsonObj) and setting bError is superfluous.  Just wait til you get done with your if/else for parsing the raw data and then do a single (!jsonObj) check and kick out with error if jsonObj is bad.  Less coding, one less variable, always good thing.  Then process your jsonObj to produce your jsonList.  Now my example doesn't do the upfront checks for the resultsList/fields, it does it a bit lower after parsing the jsonObj, and it really shouldn't.  jsonList *is* required, so that means the resultsList/fields is mandatory.  First check should really be this:
         
        if (!oRawResponse && !YAHOO.lang.isString(this.responseSchema.resultsList) && !YAHOO.lang.isArray(this.responseSchema.resultsFields))
         
        Its called peer review... once you open you your source code to the world at large it happens.  Don't agree?  Ignore it (frankly, I don't want to hear, and I'm sure no one else does, diatriabes like I already saw from someone else this morning).  Agree somewhat?  Great, use what you want, throw out the rest.  Or use it all.  Matters not to me, but perhaps a different way of looking at something might make for more robust, *complete* code.
         
         
        ----- Original Message -----
        From: Satyam
        Sent: Thursday, January 31, 2008 2:41 AM
        Subject: SPAM-LOW: Re: [ydn-javascript] DataSource and parseJSONData

        The place to pick extra information from the raw incoming data is any of the events or overridable functions mentioned in:
         
         
        This is shown in the server-side sorting and server-side paging examples in the YUI docs.  This methods are just the same for all sorts of message format, JSON, XML or whatever
         
        Nevertheless, the current arguments to those methods and events forces you to re-parse the data yourself to extract the information.  In Jenny's recent announcement, she mentions, regarding improvements in the DataSource:
         
        * access to the entire data response after it as been type-converted
        but before it has been schema-parsed
         
        which means those methods will receive the information already converted to a JavaScript object but still complete, not stripped out of the information not mentioned in the responseSchema.  That would make it even easier to pick the extra information or meta-data and it would apply to all formats, not just JSON.
         
        Satyam
         
        ----- Original Message -----
        From: Hollywood
        Sent: Thursday, January 31, 2008 1:15 AM
        Subject: [ydn-javascript] DataSource and parseJSONData

        Back to my DataTable/DataSourc e issue... am sending JSON data back with additional parameters other than just the "responseSchema. resultsList" and looks something like:
         
        {
            "count":"5",
            "selected":" asdfasdf" ,
            "params":{"start" :0,"limit" :0,"sort" :"","dir" :"","filter" :""},
            "results":[{ "Id":"123" ,"Name":" Series Warmup"}.... .]
        }
         
        But the totalCount and selected were not showin up in the data table event handlers (such as initEvent) in the response object and I was curious as to why. 
         
        So I looked through the DataSource and ran across the parseJSONData method.  It parses the JSONtext data into a JS object, and then it creates a response object but only for fields that are in the "responseSchema. resultsList" (i.e. in my case the 'results' array).  Not to mention it requires that the response.fields and response.resultsLis t are require but doesn't check for both of them up front, just one.  I updated to clean it up a bit and add in the ability to have additional parameters in addition to the "resusltsList" and "resultsFields" and below is what is the outcome.
         
        /**
         * Overridable method parses raw JSON data into a response object.
         *
         * Expects the following responseSchema object:
         *  resultsList - Tabular list of data.
         *  resultsFields - Array of fields to be used from the resultsList.
         *  params - Array of additional parameters passed with the data.
         *
         * @method parseJSONData
         * @param oRequest {Object} Request object.
         * @param oRawResponse {Object} The raw response from the live database.
         * @return {Object} Parsed response object.
         */
        YAHOO.util.DataSour ce.prototype. parseJSONData = function(oRequest, oRawResponse)
        {
            var oParsedResponse = {};
            if (!oRawResponse)
            {
                YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                oParsedResponse. error = true;
               
                return oParsedResponse;
            }
           
            var jsonObj = null;
           
            // Parse JSON object out if it's a string
            if (YAHOO.lang. isString( oRawResponse) )
            {
                // Check for latest JSON lib but divert KHTML clients
                var isNotMac = (navigator.userAgen t.toLowerCase( ).indexOf( 'khtml')= = -1);
               
                if (oRawResponse. parseJSON && isNotMac)
                    // Use the new JSON utility if available
                    jsonObj = oRawResponse. parseJSON( );
               
                // Check for YUI JSON lib but divert KHTML clients
                else if(YAHOO.lang. JSON && isNotMac)
                    // Use the JSON utility if available
                    jsonObj = YAHOO.lang.JSON. parse(oRawRespon se);
               
                // Check for older JSON lib but divert KHTML clients
                else if(window.JSON && JSON.parse && isNotMac)
                    // Use the JSON utility if available
                    jsonObj = JSON.parse(oRawResp onse);
               
                // No JSON lib found so parse the string
                else
                {
                    try
                    {
                        // Trim leading spaces
                        while ((oRawResponse. length > 0) &&
                               (oRawResponse. charAt(0) != "{") &&
                               (oRawResponse. charAt(0) != "["))
                        {
                            oRawResponse = oRawResponse. substring( 1, oRawResponse. length);
                        }
         
                        if (oRawResponse. length > 0)
                        {
                            // Strip extraneous stuff at the end
                            var objEnd = Math.max(oRawRespon se.lastIndexOf( "]"),oRawRespons e.lastIndexOf( "}"));
                            oRawResponse = oRawResponse. substring( 0,objEnd+ 1);
         
                            // Turn the string into an object literal...
                            // ...eval is necessary here
                            jsonObj = eval("(" + oRawResponse + ")");
                        }
                    }
                    catch(e) {}
                }
            }
            // Response must already be a JSON object
            else if (oRawResponse. constructor == Object)
                jsonObj = oRawResponse;
           
            if (!jsonObj)
            {
                YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                oParsedResponse. error = true;
               
                return oParsedResponse;
            }
           
            if ((this.responseSche ma.resultsList) && YAHOO.lang.isArray( this.responseSch ema.resultsField s))
            {
                var fields = this.responseSchema .resultsFields;
                var jsonList = null;
               
                // Now that we have a JSON object, parse a jsonList out of it
                if (jsonObj && jsonObj.constructor == Object)
                {
                    try
                    {
                        // eval is necessary here since schema can be of unknown depth
                        jsonList = eval("jsonObj. " + this.responseSchema .resultsList) ;
                    }
                    catch(e) {}
                }
         
                if (!jsonList)
                {
                    YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                    oParsedResponse. error = true;
                    return oParsedResponse;
                }
               
                if (jsonList && !YAHOO.lang. isArray(jsonList ))
                    jsonList = [jsonList];
                else if (!jsonList)
                    jsonList = [];
         
                oParsedResponse. results = [];
               
                // Loop through the array of all responses...
                for(var i = jsonList.length- 1; i >= 0 ; i--)
                {
                    var oResult = {};
                    var jsonResult = jsonList[i];
                    var field, key, data;
                   
                    // ...and loop through each data field value of each response
                    for(var j = fields.length- 1; j >= 0 ; j--)
                    {
                        field = fields[j];
                        key = (YAHOO.lang. isValue(field. key)) ? field.key : field;
                       
                        // ...and capture data into an array mapped according to the schema...
                        // eval is necessary here since schema can be of unknown depth
                        data = eval("jsonResult. " + key);
                        //YAHOO.log( "data: " + i + " value:" +j+" = "+dataFieldValue, "debug",this. toString( ));
                       
                        // Backward compatibility
                        if (!field.parser && field.converter)
                        {
                            field.parser = field.converter;
                            YAHOO.log("The field property converter has been deprecated in favor of parser", "warn", this.toString( ));
                        }
                       
                        if (field.parser)
                            data = field.parser. call(this, data);
                       
                        // Safety measure
                        if(data === undefined)
                            data = null;
         
                        oResult[key] = data;
                    }
                   
                    // Capture the array of data field values in an array of results
                    oParsedResponse. results.unshift( oResult);
                }
            }
               
            if (YAHOO.lang. isArray(this. responseSchema. params))
            {
                var params = this.responseSchema .params;
               
                if (jsonObj && !YAHOO.lang. isArray(jsonObj) )
                    jsonObj = [jsonObj];
                else if (!jsonObj)
                    jsonObj = [];
               
                for(var i = jsonObj.length- 1; i >= 0 ; i--)
                {
                    var oResult = {};
                    var jsonResult = jsonObj[i];
                    // ...and loop through each param value of each response
                    for(var j = params.length- 1; j >= 0 ; j--)
                    {
                        var param = params[j];
                        var key = (YAHOO.lang. isValue(param. key)) ? param.key : param;
                        // ...and capture param data into an array mapped according to the schema...
                        // eval is necessary here since schema can be of unknown depth
                        var data = eval("jsonResult. " + key);
                        //YAHOO.log( "data: " + i + " value:" +j+" = "+dataFieldValue, "debug",this. toString( ));
                       
                        // Safety measure
                        if (data === undefined)
                            data = null;
                           
                        oParsedResponse[ key] = data;
                    }
                }
               
                YAHOO.log("Parsed JSON data is " + YAHOO.lang.dump( oParsedResponse) , "info", this.toString( ));
            }
           
            return oParsedResponse;
        }
         
        Note that "responseSchema. fields" has been renamed to "response.resultsFi elds" because it works in complete conjunction with "responseSchema. resultsList" ... one can't exist without the other (at least in regards to parseJSONData) .
         
        Now not only does the "resultsList" show up in the DataTable (as before) but in the response it passes back any additional parameters defined int he "responseSchema. params" array.


        No virus found in this incoming message.
        Checked by AVG Free Edition.
        Version: 7.5.516 / Virus Database: 269.19.16/1250 - Release Date: 29/01/2008 22:20

      • Satyam
        I just deleted all that I had written when I read your last paragraph. I believe I will take the ignore it option. Satyam ... From: Hollywood To:
        Message 3 of 8 , Jan 31, 2008
        • 0 Attachment
          I just deleted all that I had written when I read your last paragraph.  I believe I will take the 'ignore it' option.
           
          Satyam
           
           
           ----- Original Message -----
          From: Hollywood
          Sent: Thursday, January 31, 2008 3:53 PM
          Subject: Re: [ydn-javascript] DataSource and parseJSONData

          Saytam,
           
          That is all well and good.  But that is not the issue.  The issue is when it gets back to the dataTable.  I'm not interested in overriding the data when its in the DataSource, but rather when it gets to the DataTable.
           
          And yes, but there are also two issues with that, its in 2.5.0 and not 2.4.1 which is current, and secondly its still an issue in that its in the DataSource and that the DataSource is sending the DataTable stripped down information.
           
          The server-side pagination/sorting examples I believe is not the correct solution.  To me the DataSource should not be modifying the DataTable.   DataTable should request data via the DataSource, the DataSource should provide that data, and then its up to the DataTable to do with it what it wants.  With the my override to the parseJSONData, instead of defining a doBeforeCallback function on the DataSource to setup the dataTable.set() for the sorting when the data is returned from the server, you can just define a doBeforeLoadData function on the DataTable and have it call the set sorting.  This keeps both operations for the sorting within the scope of the DataTable where it belongs.   The DataSource should know *nothing* about the setting up the DataTable.
           
          Lastly, and while everyone has their own coding style, when I actually took a look at the parseJSONData it from a code standpoint didn't make a whole lot of sense.  There are three conditions and unmodified parseJSONData needs to meet:  a) you must have a valid oRawResponse, b) you must have a responseSchema.resultsList defined, and c) you must have a responseSchema.fields array defined.  If you don't have all three of those then the parseJSONData isn't going to work.   In the code as it stands, there is a check for the oRawResponse and fields, but never the resultsList, so if you pass in a null or empty string you get an error during the jsonList = eval("jsonObj."....) call.  IMO (and yes, its no better or worse than anyone elses, some people not withstanding) you should check for the three conditions up front.  If those three conditions aren't satisfied, return with your error message.   Next step would attempt to parse the oRawResponse to produce your jsonObj.  Since you are in a big if/else condition, doing all the (!jsonObj) and setting bError is superfluous.  Just wait til you get done with your if/else for parsing the raw data and then do a single (!jsonObj) check and kick out with error if jsonObj is bad.  Less coding, one less variable, always good thing.  Then process your jsonObj to produce your jsonList.  Now my example doesn't do the upfront checks for the resultsList/fields, it does it a bit lower after parsing the jsonObj, and it really shouldn't.  jsonList *is* required, so that means the resultsList/fields is mandatory.  First check should really be this:
           
          if (!oRawResponse && !YAHOO.lang.isString(this.responseSchema.resultsList) && !YAHOO.lang.isArray(this.responseSchema.resultsFields))
           
          Its called peer review... once you open you your source code to the world at large it happens.  Don't agree?  Ignore it (frankly, I don't want to hear, and I'm sure no one else does, diatriabes like I already saw from someone else this morning).  Agree somewhat?  Great, use what you want, throw out the rest.  Or use it all.  Matters not to me, but perhaps a different way of looking at something might make for more robust, *complete* code.
           
           
          ----- Original Message -----
          From: Satyam
          Sent: Thursday, January 31, 2008 2:41 AM
          Subject: SPAM-LOW: Re: [ydn-javascript] DataSource and parseJSONData

          The place to pick extra information from the raw incoming data is any of the events or overridable functions mentioned in:
           
           
          This is shown in the server-side sorting and server-side paging examples in the YUI docs.  This methods are just the same for all sorts of message format, JSON, XML or whatever
           
          Nevertheless, the current arguments to those methods and events forces you to re-parse the data yourself to extract the information.  In Jenny's recent announcement, she mentions, regarding improvements in the DataSource:
           
          * access to the entire data response after it as been type-converted
          but before it has been schema-parsed
           
          which means those methods will receive the information already converted to a JavaScript object but still complete, not stripped out of the information not mentioned in the responseSchema.  That would make it even easier to pick the extra information or meta-data and it would apply to all formats, not just JSON.
           
          Satyam
           
          ----- Original Message -----
          From: Hollywood
          Sent: Thursday, January 31, 2008 1:15 AM
          Subject: [ydn-javascript] DataSource and parseJSONData

          Back to my DataTable/DataSourc e issue... am sending JSON data back with additional parameters other than just the "responseSchema. resultsList" and looks something like:
           
          {
              "count":"5",
              "selected":" asdfasdf" ,
              "params":{"start" :0,"limit" :0,"sort" :"","dir" :"","filter" :""},
              "results":[{ "Id":"123" ,"Name":" Series Warmup"}.... .]
          }
           
          But the totalCount and selected were not showin up in the data table event handlers (such as initEvent) in the response object and I was curious as to why. 
           
          So I looked through the DataSource and ran across the parseJSONData method.  It parses the JSONtext data into a JS object, and then it creates a response object but only for fields that are in the "responseSchema. resultsList" (i.e. in my case the 'results' array).  Not to mention it requires that the response.fields and response.resultsLis t are require but doesn't check for both of them up front, just one.  I updated to clean it up a bit and add in the ability to have additional parameters in addition to the "resusltsList" and "resultsFields" and below is what is the outcome.
           
          /**
           * Overridable method parses raw JSON data into a response object.
           *
           * Expects the following responseSchema object:
           *  resultsList - Tabular list of data.
           *  resultsFields - Array of fields to be used from the resultsList.
           *  params - Array of additional parameters passed with the data.
           *
           * @method parseJSONData
           * @param oRequest {Object} Request object.
           * @param oRawResponse {Object} The raw response from the live database.
           * @return {Object} Parsed response object.
           */
          YAHOO.util.DataSour ce.prototype. parseJSONData = function(oRequest, oRawResponse)
          {
              var oParsedResponse = {};
              if (!oRawResponse)
              {
                  YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                  oParsedResponse. error = true;
                 
                  return oParsedResponse;
              }
             
              var jsonObj = null;
             
              // Parse JSON object out if it's a string
              if (YAHOO.lang. isString( oRawResponse) )
              {
                  // Check for latest JSON lib but divert KHTML clients
                  var isNotMac = (navigator.userAgen t.toLowerCase( ).indexOf( 'khtml')= = -1);
                 
                  if (oRawResponse. parseJSON && isNotMac)
                      // Use the new JSON utility if available
                      jsonObj = oRawResponse. parseJSON( );
                 
                  // Check for YUI JSON lib but divert KHTML clients
                  else if(YAHOO.lang. JSON && isNotMac)
                      // Use the JSON utility if available
                      jsonObj = YAHOO.lang.JSON. parse(oRawRespon se);
                 
                  // Check for older JSON lib but divert KHTML clients
                  else if(window.JSON && JSON.parse && isNotMac)
                      // Use the JSON utility if available
                      jsonObj = JSON.parse(oRawResp onse);
                 
                  // No JSON lib found so parse the string
                  else
                  {
                      try
                      {
                          // Trim leading spaces
                          while ((oRawResponse. length > 0) &&
                                 (oRawResponse. charAt(0) != "{") &&
                                 (oRawResponse. charAt(0) != "["))
                          {
                              oRawResponse = oRawResponse. substring( 1, oRawResponse. length);
                          }
           
                          if (oRawResponse. length > 0)
                          {
                              // Strip extraneous stuff at the end
                              var objEnd = Math.max(oRawRespon se.lastIndexOf( "]"),oRawRespons e.lastIndexOf( "}"));
                              oRawResponse = oRawResponse. substring( 0,objEnd+ 1);
           
                              // Turn the string into an object literal...
                              // ...eval is necessary here
                              jsonObj = eval("(" + oRawResponse + ")");
                          }
                      }
                      catch(e) {}
                  }
              }
              // Response must already be a JSON object
              else if (oRawResponse. constructor == Object)
                  jsonObj = oRawResponse;
             
              if (!jsonObj)
              {
                  YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                  oParsedResponse. error = true;
                 
                  return oParsedResponse;
              }
             
              if ((this.responseSche ma.resultsList) && YAHOO.lang.isArray( this.responseSch ema.resultsField s))
              {
                  var fields = this.responseSchema .resultsFields;
                  var jsonList = null;
                 
                  // Now that we have a JSON object, parse a jsonList out of it
                  if (jsonObj && jsonObj.constructor == Object)
                  {
                      try
                      {
                          // eval is necessary here since schema can be of unknown depth
                          jsonList = eval("jsonObj. " + this.responseSchema .resultsList) ;
                      }
                      catch(e) {}
                  }
           
                  if (!jsonList)
                  {
                      YAHOO.log("JSON data could not be parsed: " + YAHOO.lang.dump( oRawResponse) , "error", this.toString( ));
                      oParsedResponse. error = true;
                      return oParsedResponse;
                  }
                 
                  if (jsonList && !YAHOO.lang. isArray(jsonList ))
                      jsonList = [jsonList];
                  else if (!jsonList)
                      jsonList = [];
           
                  oParsedResponse. results = [];
                 
                  // Loop through the array of all responses...
                  for(var i = jsonList.length- 1; i >= 0 ; i--)
                  {
                      var oResult = {};
                      var jsonResult = jsonList[i];
                      var field, key, data;
                     
                      // ...and loop through each data field value of each response
                      for(var j = fields.length- 1; j >= 0 ; j--)
                      {
                          field = fields[j];
                          key = (YAHOO.lang. isValue(field. key)) ? field.key : field;
                         
                          // ...and capture data into an array mapped according to the schema...
                          // eval is necessary here since schema can be of unknown depth
                          data = eval("jsonResult. " + key);
                          //YAHOO.log( "data: " + i + " value:" +j+" = "+dataFieldValue, "debug",this. toString( ));
                         
                          // Backward compatibility
                          if (!field.parser && field.converter)
                          {
                              field.parser = field.converter;
                              YAHOO.log("The field property converter has been deprecated in favor of parser", "warn", this.toString( ));
                          }
                         
                          if (field.parser)
                              data = field.parser. call(this, data);
                         
                          // Safety measure
                          if(data === undefined)
                              data = null;
           
                          oResult[key] = data;
                      }
                     
                      // Capture the array of data field values in an array of results
                      oParsedResponse. results.unshift( oResult);
                  }
              }
                 
              if (YAHOO.lang. isArray(this. responseSchema. params))
              {
                  var params = this.responseSchema .params;
                 
                  if (jsonObj && !YAHOO.lang. isArray(jsonObj) )
                      jsonObj = [jsonObj];
                  else if (!jsonObj)
                      jsonObj = [];
                 
                  for(var i = jsonObj.length- 1; i >= 0 ; i--)
                  {
                      var oResult = {};
                      var jsonResult = jsonObj[i];
                      // ...and loop through each param value of each response
                      for(var j = params.length- 1; j >= 0 ; j--)
                      {
                          var param = params[j];
                          var key = (YAHOO.lang. isValue(param. key)) ? param.key : param;
                          // ...and capture param data into an array mapped according to the schema...
                          // eval is necessary here since schema can be of unknown depth
                          var data = eval("jsonResult. " + key);
                          //YAHOO.log( "data: " + i + " value:" +j+" = "+dataFieldValue, "debug",this. toString( ));
                         
                          // Safety measure
                          if (data === undefined)
                              data = null;
                             
                          oParsedResponse[ key] = data;
                      }
                  }
                 
                  YAHOO.log("Parsed JSON data is " + YAHOO.lang.dump( oParsedResponse) , "info", this.toString( ));
              }
             
              return oParsedResponse;
          }
           
          Note that "responseSchema. fields" has been renamed to "response.resultsFi elds" because it works in complete conjunction with "responseSchema. resultsList" ... one can't exist without the other (at least in regards to parseJSONData) .
           
          Now not only does the "resultsList" show up in the DataTable (as before) but in the response it passes back any additional parameters defined int he "responseSchema. params" array.


          No virus found in this incoming message.
          Checked by AVG Free Edition.
          Version: 7.5.516 / Virus Database: 269.19.16/1250 - Release Date: 29/01/2008 22:20


          No virus found in this incoming message.
          Checked by AVG Free Edition.
          Version: 7.5.516 / Virus Database: 269.19.17/1252 - Release Date: 30/01/2008 20:51
        • y_lsmith
          ... when it gets back to the dataTable. I m not interested in overriding the data when its in the DataSource, but rather when it gets to the DataTable. ...
          Message 4 of 8 , Jan 31, 2008
          • 0 Attachment
            --- In ydn-javascript@yahoogroups.com, "Hollywood" <impulsegto@...> wrote:
            >
            > That is all well and good. But that is not the issue. The issue is
            when it gets back to the dataTable. I'm not interested in overriding
            the data when its in the DataSource, but rather when it gets to the
            DataTable.
            >
            > The server-side pagination/sorting examples I believe is not the
            correct solution. To me the DataSource should not be modifying the
            DataTable. DataTable should request data via the DataSource, the
            DataSource should provide that data, and then its up to the DataTable
            to do with it what it wants. With the my override to the
            parseJSONData, instead of defining a doBeforeCallback function on the
            DataSource to setup the dataTable.set() for the sorting when the data
            is returned from the server, you can just define a doBeforeLoadData
            function on the DataTable and have it call the set sorting. This
            keeps both operations for the sorting within the scope of the
            DataTable where it belongs. The DataSource should know *nothing*
            about the setting up the DataTable.

            >
            >
            > And yes, but there are also two issues with that, its in 2.5.0 and
            not 2.4.1 which is current, and secondly its still an issue in that
            its in the DataSource and that the DataSource is sending the DataTable
            stripped down information.

            > Lastly, and while everyone has their own coding style, when I
            actually took a look at the parseJSONData it from a code standpoint
            didn't make a whole lot of sense. There are three conditions and
            unmodified parseJSONData needs to meet: a) you must have a valid
            oRawResponse, b) you must have a responseSchema.resultsList defined,
            and c) you must have a responseSchema.fields array defined. If you
            don't have all three of those then the parseJSONData isn't going to
            work. In the code as it stands, there is a check for the
            oRawResponse and fields, but never the resultsList, so if you pass in
            a null or empty string you get an error during the jsonList =
            eval("jsonObj."....) call. IMO (and yes, its no better or worse than
            anyone elses, some people not withstanding) you should check for the
            three conditions up front. If those three conditions aren't
            satisfied, return with your error message. Next step would attempt
            to parse the oRawResponse to produce your jsonObj. Since you are in a
            big if/else condition, doing all the (!jsonObj) and setting bError is
            superfluous. Just wait til you get done with your if/else for parsing
            the raw data and then do a single (!jsonObj) check and kick out with
            error if jsonObj is bad. Less coding, one less variable, always good
            thing. Then process your jsonObj to produce your jsonList. Now my
            example doesn't do the upfront checks for the resultsList/fields, it
            does it a bit lower after parsing the jsonObj, and it really
            shouldn't. jsonList *is* required, so that means the
            resultsList/fields is mandatory. First check should really be this:
            >
            > if (!oRawResponse &&
            !YAHOO.lang.isString(this.responseSchema.resultsList) &&
            !YAHOO.lang.isArray(this.responseSchema.resultsFields))
            >


            Hollywood,

            Thanks for the feedback! We appreciate the code review. It looks
            like you found some areas in DataSource and DataTable that we had also
            noted needed some improvement. I hope you'll take a look at the
            changes in 2.5. Among other things, parseJSONData got a good deal of
            attention, and the parsed-but-not-reduced data will be provided from
            the DataSource as well. Hopefully you'll find that all your
            requirements will be met without the need for extensive customization.

            In 2.4.1 land, it sounds like yours is a clear case for either
            overriding DataSource's parseJSONData as you have done or overriding
            the DataTable's doBeforeLoadData to, as Satyam suggested, reparse the
            oRawResponse JSON to access the additional response payload. As eval
            can be quite expensive, you might try benchmarking a reparse in
            doBeforeLoadData vs your parseJSONData override. With smaller JSON
            strings, it *might* be faster to do a single JSON parse followed by
            explicit object access than to execute a series of evals to pull key
            data for your params array.

            By all means, if you (or anyone) see a performance issue or bug,
            please file a bug on SourceForge.

            If, as in this case, you have a suggestion for how to override a
            function to solve a particular problem, we encourage you to share. We
            all benefit.

            Thanks,
            Luke
          • Hollywood
            Luke, I am anxiously, as everyone I assume, am looking forward to 2.5 especially with the DataTable/DataSource enhancements. I ll definetly check out the
            Message 5 of 8 , Jan 31, 2008
            • 0 Attachment
              Luke,
               
              I am anxiously, as everyone I assume, am looking forward to 2.5 especially with the DataTable/DataSource enhancements.  I'll definetly check out the parseJSONData updates as I would definetly perfer to use stuff as is as it makes migration to new builds much less painful!
               
              Indeed, you are right, it may be faster to do it that way.  However, from a programming point of view, I wanted to keep things as similiar in nature as possible; i.e. the resultsList/field combo works in way X, params should work in much the same way.
               
              However in speaking of all this, I do begin to wonder if it is really the DataSource's place to be dealing with tabular data only.  Should not the DataSource just deal with being a wrapper around the connection and being able to return and say in the case of JSON (or XML, etc.) data return a parsed object (i.e. just the jsonObj in parseJSONData) and then let the client, i.e. DataTable, do any additional work such as dealing with the "resultsList/fields"?  DataSource seems to be a very useable piece of functionality for many different data fetch tasks, hate to see it locked down to only being able to deal with tabular info as it sorta is now with regards to at least JSON parsing.
               
              ----- Original Message -----
              From: y_lsmith
              Sent: Thursday, January 31, 2008 10:30 AM
              Subject: [ydn-javascript] Re: DataSource and parseJSONData

              --- In ydn-javascript@ yahoogroups. com, "Hollywood" <impulsegto@ ...> wrote:
              >
              > That is all well and good. But that is not the issue. The issue is
              when it gets back to the dataTable. I'm not interested in overriding
              the data when its in the DataSource, but rather when it gets to the
              DataTable.
              >
              > The server-side pagination/sorting examples I believe is not the
              correct solution. To me the DataSource should not be modifying the
              DataTable. DataTable should request data via the DataSource, the
              DataSource should provide that data, and then its up to the DataTable
              to do with it what it wants. With the my override to the
              parseJSONData, instead of defining a doBeforeCallback function on the
              DataSource to setup the dataTable.set( ) for the sorting when the data
              is returned from the server, you can just define a doBeforeLoadData
              function on the DataTable and have it call the set sorting. This
              keeps both operations for the sorting within the scope of the
              DataTable where it belongs. The DataSource should know *nothing*
              about the setting up the DataTable.

              >
              >
              > And yes, but there are also two issues with that, its in 2.5.0 and
              not 2.4.1 which is current, and secondly its still an issue in that
              its in the DataSource and that the DataSource is sending the DataTable
              stripped down information.

              > Lastly, and while everyone has their own coding style, when I
              actually took a look at the parseJSONData it from a code standpoint
              didn't make a whole lot of sense. There are three conditions and
              unmodified parseJSONData needs to meet: a) you must have a valid
              oRawResponse, b) you must have a responseSchema. resultsList defined,
              and c) you must have a responseSchema. fields array defined. If you
              don't have all three of those then the parseJSONData isn't going to
              work. In the code as it stands, there is a check for the
              oRawResponse and fields, but never the resultsList, so if you pass in
              a null or empty string you get an error during the jsonList =
              eval("jsonObj. "....) call. IMO (and yes, its no better or worse than
              anyone elses, some people not withstanding) you should check for the
              three conditions up front. If those three conditions aren't
              satisfied, return with your error message. Next step would attempt
              to parse the oRawResponse to produce your jsonObj. Since you are in a
              big if/else condition, doing all the (!jsonObj) and setting bError is
              superfluous. Just wait til you get done with your if/else for parsing
              the raw data and then do a single (!jsonObj) check and kick out with
              error if jsonObj is bad. Less coding, one less variable, always good
              thing. Then process your jsonObj to produce your jsonList. Now my
              example doesn't do the upfront checks for the resultsList/ fields, it
              does it a bit lower after parsing the jsonObj, and it really
              shouldn't. jsonList *is* required, so that means the
              resultsList/ fields is mandatory. First check should really be this:
              >
              > if (!oRawResponse &&
              !YAHOO.lang. isString( this.responseSch ema.resultsList) &&
              !YAHOO.lang. isArray(this. responseSchema. resultsFields) )
              >

              Hollywood,

              Thanks for the feedback! We appreciate the code review. It looks
              like you found some areas in DataSource and DataTable that we had also
              noted needed some improvement. I hope you'll take a look at the
              changes in 2.5. Among other things, parseJSONData got a good deal of
              attention, and the parsed-but-not- reduced data will be provided from
              the DataSource as well. Hopefully you'll find that all your
              requirements will be met without the need for extensive customization.

              In 2.4.1 land, it sounds like yours is a clear case for either
              overriding DataSource's parseJSONData as you have done or overriding
              the DataTable's doBeforeLoadData to, as Satyam suggested, reparse the
              oRawResponse JSON to access the additional response payload. As eval
              can be quite expensive, you might try benchmarking a reparse in
              doBeforeLoadData vs your parseJSONData override. With smaller JSON
              strings, it *might* be faster to do a single JSON parse followed by
              explicit object access than to execute a series of evals to pull key
              data for your params array.

              By all means, if you (or anyone) see a performance issue or bug,
              please file a bug on SourceForge.

              If, as in this case, you have a suggestion for how to override a
              function to solve a particular problem, we encourage you to share. We
              all benefit.

              Thanks,
              Luke

            Your message has been successfully submitted and would be delivered to recipients shortly.