skip to Main Content

When calling findItemsAdvanced with RESPONSE-DATA-FORMAT=XML, the results are as expected, e.g:

<findItemsAdvancedResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
  <ack>Success</ack>
  <version>1.13.0</version>
  <timestamp>2014-11-16T20:59:57.588Z</timestamp>
  <searchResult count="0"/>
  <paginationOutput>
    <pageNumber>0</pageNumber>
    <entriesPerPage>100</entriesPerPage>
    <totalPages>0</totalPages>
    <totalEntries>0</totalEntries>
  </paginationOutput>
  <itemSearchURL>http://www.ebay.co.uk/sch/i.html?_nkw=mytest1</itemSearchURL>
</findItemsAdvancedResponse>

But calling the same with RESPONSE-DATA-FORMAT=JSON, individual elements are all wrapped in []:

{"findItemsAdvancedResponse":[
  {"ack":["Success"],
   "version":["1.13.0"],
   "timestamp":["2014-11-16T20:58:14.639Z"],
   "searchResult":[
    {"@count":"0"}],
   "paginationOutput":[
     {"pageNumber":["0"],
      "entriesPerPage":["100"],
      "totalPages":["0"],
      "totalEntries":["0"]}],
   "itemSearchURL":["http://www.ebay.co.uk/sch/i.html?&_nkw=mytest1"]
  }]
}

This seems to make it a pain to extract results using Javascript e.g:

response.findItemsAdvancedResponse[0].paginationOutput[0].pageNumber[0]

Am I doing missing something here or doing something wrong? (If not will consider requesting the results in XML and using an XML=>JSON conversion tool…)

5

Answers


  1. This is JSON. What did you expect JSON to look like? 🙂

    {"findItemsAdvancedResponse":[
      {"ack":["Success"],
       "version":["1.13.0"],
       "timestamp":["2014-11-16T20:58:14.639Z"],
       "searchResult":[
        {"@count":"0"}],
       "paginationOutput":[
         {"pageNumber":["0"],
          "entriesPerPage":["100"],
          "totalPages":["0"],
          "totalEntries":["0"]}],
       "itemSearchURL":["http://www.ebay.co.uk/sch/i.html?&_nkw=mytest1"]
      }]
    }
    

    Try going to http://jsonviewer.stack.hu/ and pasting the JSON string into the “Text”-section and clicking the “Viewer” tab for a visual representation of the JSON data.

    You may want to visit the Wikipedia article on JSON (JavaScript Object Notation):
    http://en.wikipedia.org/wiki/JSON#Data_types.2C_syntax_and_example

    Login or Signup to reply.
  2. Seems no-one else is bothered by this?

    I’m using AngularJS and I want to have the Ebay API as a backend. I have to write a $resource interceptor to collapse all arrays that only have 1 child to remove the redundant [] brackets.

    A generic interceptor could solve this elegantly however I do think this is a bug.

    I’ve asked the question on the Ebay Developer Form here: https://forums.developer.ebay.com/questions/16385/why-does-search-return-json-items-as-array.html#answer-16386

    I have referenced this page on the Ebay forum – hope that helps others.

    Edit:

    … and for completeness, here is the code I used. It might not be pretty, but it worked for me. YMMV

    var resp = {"findItemsAdvancedResponse":[
       {"ack":["Success"],
        "version":["1.13.0"],
        "timestamp":["2014-11-16T20:58:14.639Z"],
        "searchResult":[
         {"@count":"0"}],
        "paginationOutput":[
          {"pageNumber":["0"],
           "entriesPerPage":["100"],
           "totalPages":["0"],
           "totalEntries":["0"]}],
        "itemSearchURL":["http://www.ebay.co.uk/sch/i.html?&_nkw=mytest1"]
       }]
     };
    
    var flatten = function( obj ) {
        var ret = {};
    
      if( String === obj.constructor || Number === obj.constructor ) {
        return obj;
      }
    
      for(var prop in obj) {
        if(!obj.hasOwnProperty(prop)) continue;
    
        if( String === obj[prop].constructor || Number === obj[prop].constructor ) {
            ret[prop] = obj[prop];
          continue;
        }
    
        if( Object.prototype.toString.call( obj[prop] ) === '[object Array]' ) {
          if( obj[prop].length==0 )
            ret[prop] = null;
          if( obj[prop].length==1 && "0" in obj[prop] ) {
            ret[prop] = flatten(obj[prop][0]);
          } else {
            ret[prop] = flatten(obj[prop]);
          }
          continue; // skip below: all arrays are Objects...!
        }
    
        if( Object === obj[prop].constructor ) {
          ret[prop] = flatten( obj[prop] );
          continue;
        }
    
      }
      return ret;
    };
    
    console.log( resp );
    resp = flatten( resp );
    console.log( resp );
    console.log( resp.findItemsAdvancedResponse.ack );
    
    Login or Signup to reply.
  3. This is very similar to DerekC’s parse function just quite a bit faster. It is geared towards simply finding elements that are arrays with Array.isArray() and a length of 1 with values that are not objects. Nothing fancy, super clean and super fast.

    The function is called ebayFormat, just below the same response object that DerekC used.

    var resp = {"findItemsAdvancedResponse":[
       {"ack":["Success"],
        "version":["1.13.0"],
        "timestamp":["2014-11-16T20:58:14.639Z"],
        "searchResult":[
         {"@count":"0"}],
        "paginationOutput":[
          {"pageNumber":["0"],
           "entriesPerPage":["100"],
           "totalPages":["0"],
           "totalEntries":["0"]}],
        "itemSearchURL":["http://www.ebay.co.uk/sch/i.html?&_nkw=mytest1"]
       }]
     };
    
      function ebayFormat(item) {
        if (typeof item === 'object') {
          if (Array.isArray(item) && item.length === 1 && typeof item[0] !== 'object') item = item[0];
          else {
            var keys = Object.keys(item),
              i = 0,
              len = keys.length;
            for (; i < len; i++) {
              if (typeof item[keys[i]] === 'object') item[keys[i]] = ebayFormat(item[keys[i]]);
            }
          }
        }
        return item;
      }
    
    console.log( resp );
    resp = ebayFormat( resp );
    console.log( resp );
    console.log( resp.findItemsAdvancedResponse.ack );
    
    Login or Signup to reply.
  4. I got the same problem, I made a recursive function to solve it (remove array when array length=1 and is not exclude)

    objJsonFromEbay = findAndCorrect(objJsonFromEbay);
    
        function findAndCorrect(obj){
    
            let o = obj,
                exclu = ['item'];
    
            for (const key in o) {
                if (o.hasOwnProperty(key)) {
                    const val = o[key];
    
                    if(Array.isArray(val) && val.length == 1){
                        if(exclu.indexOf(key) == -1)
                            o[key] = val[0];
                        o[key] = findAndCorrect(o[key]);
                    }else if(!Array.isArray(val) && typeof val == 'object'){                        
                        o[key] = findAndCorrect(val);
                    }
                }
            }
            return o;
        }
    

    exclu is a Array for each element that you expect keep in a Array format.
    Could be useful if ever you use it to get products or another data that you expect in a Array

    Login or Signup to reply.
  5. I had the same issue, and was curious if I’d still have issues if I chose to use an XML response versus a JSON response, and use an XML-to-JSON converter on the returned data — lo and behold, still the exact same issue.

    The converter I would end up deciding to use is called xml2js, which seems to be extremely popular on NPM (north of 3.5M monthly downloads according to NPM at the time of this answer).

    xml2js has an option called explicitArray within its parseString behavior, which behaves as they document:

    Always put child nodes in an array if true; otherwise an array is created only if there is more than one.

    This behavior seems to emulate some of the answers listed here, but because it’s a part of a widely-used community solution, I feel more comfortable using it versus a home-grown solution.

    In practice, this looks as simple as:

    import { parseString as xml2js } from 'xml2js';
    
    ...
    
    xml2js(someXmlString, { explicitArray: false }, (err, results) => {
      // do something with `results`
    });
    

    https://www.npmjs.com/package/xml2js

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search