Steve Chambers Steve Chambers - 1 month ago 19
Javascript Question

Why are findItemsAdvanced (eBay finding API) JSON result elements all arrays?

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...)

Answer

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 );