1

I'm attempting to recreate a Python script I wrote in Node/js and I'm having trouble wrapping my head around the asynchronous/callback way of it all.

The script is fairly simple and uses two basic HTTP requests to eBay's API. The first request gets a list of resulting item ids, then the second request gets specific information on each item (description/listing information etc). In Python this was fairly simple and I used a simple loop. It wasn't fast by any means, but it worked.

In javascript, however, I'm struggling to get the same functionality. My code right now is as follows:

var ebay = require('ebay-api'); 
var params ={};

params.keywords = ["pS4"];
var pages = 2;
var perPage = 2;


ebay.paginateGetRequest({

serviceName: 'FindingService',
opType: 'findItemsAdvanced',
appId: '',
params: params,
pages: pages,
perPage: perPage,
parser: ebay.parseItemsFromResponse
},

function allItemsCallback(error,items){
    if(error) throw error;

    console.log('FOUND', items.length, 'items from', pages, 'pages');

    for (var i=0; i<items.length; i++){

        getSingle(items[i].itemId);

    }
}   

);

function getSingle(id){

console.log("hello");
ebay.ebayApiGetRequest({

    'serviceName': 'Shopping',
    'opType': 'GetSingleItem',
    'appId': '',     

    params: {
    'ItemId': id ,
     'includeSelector': 'Description' 
    }



},
    function(error, data) {
        if (error) throw error;
        console.dir(data);  //single item data I want

    }
);
}

This is one attempt of many, but I'm recieving "possible EventEmitter memory leak detected" warnings and it eventually breaks with a "Error:Bad 'ack' code undefined errorMessage? null". I'm fairly sure this just has to do with proper utilization of callbacks but I'm unsure how to properly go about it. Any answers or help would be greatly appreciated. I apologize if this isn't a good question, if so please let me know how to correctly go about asking.

4
  • Have a look at using something like node-async to do this - it can handle the loops for you and manage the completion callback. Commented Aug 19, 2015 at 18:55
  • my understanding was that the request would be be processed -> generates a response -> callback is called -> 2ndRequest is processed for each item. Is that not the general dataflow? Commented Aug 19, 2015 at 18:57
  • No.. writing out an answer that describes it. Commented Aug 19, 2015 at 18:58
  • welp.. sorry I'm an intern trying to learn as much as I can and I'm unfamiliar with web development in general haha Commented Aug 19, 2015 at 19:02

1 Answer 1

1

Node.js's asynchronous event chain is built on callbacks. Rather than:

getSingle(items[i].itemId);

You'll need to write a callback into that function that executes once the parent function is complete:

getSingle(items[i].itemId, function(err, data) {
     // now you can access the data   
});

And because ebay.ebayApiGetRequest is a lengthy function, the callback that tells its parent function that it's done must be called after that completes, like so:

ebay.ebayApiGetRequest({
        //
    },
    function(error, data) {
        callback(error, data);
    }
);

But of course, if the parent function getSingle doesn't support a callback, then it won't go anywhere. So you'll need to support a callback param there as well. Here's the full script, rewritten using the event-driven callback model:

var ebay = require('ebay-api');
var async = require('async');
var params = {};

params.keywords = ["pS4"];
var pages = 2;
var perPage = 2;


ebay.paginateGetRequest({
        serviceName: 'FindingService',
        opType: 'findItemsAdvanced',
        appId: '',
        params: params,
        pages: pages,
        perPage: perPage,
        parser: ebay.parseItemsFromResponse
    },
    function allItemsCallback(error, items) {
        if (error) throw error;

        console.log('FOUND', items.length, 'items from', pages, 'pages');

        async.each(items, function(item, callback) {
            getSingle(item.itemId, function(err, data) {
                callback(err, data);
            });
        }, function(err, results) {
            // now results is an array of all the data objects
        });
    }
);

function getSingle(id, callback) {
    console.log("hello");
    ebay.ebayApiGetRequest({
            'serviceName': 'Shopping',
            'opType': 'GetSingleItem',
            'appId': '',
            params: {
                'ItemId': id,
                'includeSelector': 'Description'
            }
        },
        function(error, data) {
            if (error) throw error;
            console.dir(data); //single item data I want
            callback(error, data);
        }
    );
}
Sign up to request clarification or add additional context in comments.

5 Comments

This was very helpful, thank you for the clear explanation. I apologize for my ignorance, the world of node is a whole new beast for me.
Haha! Don't worry, it's a lot to wrap your head around ;)
I'm still in that "intern realizing how much college didn't teach" phase, but I appreciate the help!
Honestly, the tech scene changes faster than colleges/universities can keep up anyway!
I feel like a degree really just helps one better understand google results :P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.