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

DataSource and parseJSONData

Expand Messages
  • Hollywood
    Back to my DataTable/DataSource issue... am sending JSON data back with additional parameters other than just the responseSchema.resultsList and looks
    Message 1 of 8 , Jan 30, 2008
    • 0 Attachment
      Back to my DataTable/DataSource 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.resultsList 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.DataSource.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.userAgent.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(oRawResponse);
             
              // 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(oRawResponse);
             
              // 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(oRawResponse.lastIndexOf("]"),oRawResponse.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.responseSchema.resultsList) && YAHOO.lang.isArray(this.responseSchema.resultsFields))
          {
              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.resultsFields" 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.
    • Satyam
      The place to pick extra information from the raw incoming data is any of the events or overridable functions mentioned in:
      Message 2 of 8 , Jan 31, 2008
      • 0 Attachment
        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/DataSource 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.resultsList 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.DataSource.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.userAgent.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(oRawResponse);
               
                // 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(oRawResponse);
               
                // 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(oRawResponse.lastIndexOf("]"),oRawResponse.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.responseSchema.resultsList) && YAHOO.lang.isArray(this.responseSchema.resultsFields))
            {
                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.resultsFields" 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
      • Federico Galassi
        First line of online documentation reads: The DataSource Utility provides a common configurable interface for other components to fetch tabular data from a
        Message 3 of 8 , Jan 31, 2008
        • 0 Attachment
          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
          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 4 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 5 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 6 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 7 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 8 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.