0

I have the following code in a Node.js application:

var curlStatus = ""; 
var curlBody = ""; 
var curlHeaders = ""; 
var curlInfo = curl.on('end', function( statusCode, body, headers){
    curlStatus = statusCode; 
    curlBody = body; 
    curlHeaders = headers; 

    //this.close(); 
    return {status: curlStatus, body: curlBody, headers: curlHeaders}; 
}); 

curl.on('error', function(){
    console.log("CURL ERROR");
}); 

curl.perform(); 

Placing a breakpoint on return {status: curlStatus, body: curlBody, headers: curlHeaders}; shows that the body, headers, and statusCode are being successfully populated. However, putting a breakpoint after curl.perform() shows that the curlStatus, curlBody, and curlHeaders variables are still empty strings. How do I pass the information to the parent function?

jonathancardoso
  • 11,737
  • 7
  • 53
  • 72
Sara Fuerst
  • 5,688
  • 8
  • 43
  • 86
  • 1
    The execution in javascript is not essentially sequential (better to think that way), the callback function passed into `curl.on('end')` is executed at a much latter time after `curl.perform`. Thus a breakpoint just right after `curl.perform()` won't show you anything. – zeronone Apr 28 '16 at 15:35

2 Answers2

2

Welcome to javascript and asynchronous problem.

When you do curl.perform();, the request will start but isn't yet done, that why your variable curlX are not yet populated.
Once the request is done, the callback that you defined with url.on('end', function... is called, and you will populate these variables.

Cyrbil
  • 6,341
  • 1
  • 24
  • 40
  • Ah okay, so theoretically I could use something like a promise to fix this, right? – Sara Fuerst Apr 28 '16 at 15:35
  • Yes, you can wrap everything in a Promise and get your results. Or write the next step of you script inside your callback. – Cyrbil Apr 28 '16 at 15:40
2

I'm the author of the addon.

If you have issues with the async interface, or need a synchronous solution, I've added support for Easy handles some time ago, they are used almost exactly like the libcurl easy interface.

var Easy = require( 'node-libcurl' ).Easy,
    Curl = require( 'node-libcurl' ).Curl,
    url = process.argv[2] || 'http://www.google.com',
    ret,
    ch;

ch = new Easy();

ch.setOpt( Curl.option.URL, url );

ch.setOpt( Curl.option.HEADERFUNCTION, function( buf, size, nmemb ) {

    console.log( 'HEADERFUNCTION: ' );
    console.log( arguments );

    return size * nmemb;
});

ch.setOpt( Curl.option.WRITEFUNCTION, function( buf, size, nmemb ) {

    console.log( 'WRITEFUNCTION: ' );
    console.log( arguments );

    return size * nmemb;
});

ret = ch.perform();

ch.close();

console.log( ret, ret == Curl.code.CURLE_OK, Easy.strError( ret ) );

It's less user friendly however. Since now you need to build the body array and create the headers object yourself.

HEADERFUNCTION and WRITEFUNCTION callbacks are going to receive the response body and headers chunks, respectively. buf is a Node.js Buffer object.

jonathancardoso
  • 11,737
  • 7
  • 53
  • 72