Keatinge
Keatinge

Reputation: 4341

Promise is undefined in procedural code in nodejs

I'm very new to async languages like nodejs, I'm trying to write a web scraper that will visit a link, download a code, extract with regex, THEN visit another link using that code. I'm aware I could use callbacks, but I expect to have to go 8-9 levels deep, I think promises is the way to go (is there a better way?)

var promise = require("promise");
var request = require("request");

login();

function get_login_code()
{
    request.get("someurl.com", function (error, response, body)
    {
        // just for example
        body = 'TOKEN" value="hello world"';
        var login_code = body.match(/.TOKEN" value="([^"]+)../i);
        return login_code
    });
}

function login()
{
    var login_promise = promise.resolve(get_login_code());
    console.log(login_promise);

}

I've tried a bunch of combinations of messing around with promises, but I either always get undefined or a promise which doesn't have a value. I don't want to nest promise functions inside promises because that's exactly the same thing as callback hell. Can someone tell me what I'm doing wrong, I really want this code to be procedural and not 8 callbacks. In the ideal world promise.resolve just waits until get_login_code() returns the actual code, not undefined.

Output:

Promise { _45: 0, _81: 1, _65: undefined, _54: null }

Desired Output:

hello world

Upvotes: 0

Views: 5748

Answers (2)

Sergey Lapin
Sergey Lapin

Reputation: 2693

What your code do:

  • calls get_login_code that returns nothing (i.e. undefined)
  • inside of login function you create a new promise that is immediately resolved to the result of get_login_code, i.e. undefined.

Thus, you do not use login_code at all.

To make it work, you should make get_login_code to return a promise that will be resolved to login_code. Consider you use promise npm module, the code may look like:

// uppercased, it's a constructor
var Promise = require("promise");
var request = require("request");

login();

function get_login_code()
{
    return new Promise(function (resolve, reject) {
      request.get("someurl.com", function (error, response, body) {
        if (err) {
            reject(err);
            return;
        }
        // just for example
        body = 'TOKEN" value="hello world"';
        var login_code = body.match(/.TOKEN" value="([^"]+)../i);
        resolve(login_code);
      });
    });
}

function login()
{
    // return a new promise to use in subsequent operations
    return get_login_code()
        .then(function(login_code) {
            console.log(login_code);
        });
}

Upvotes: 2

digit
digit

Reputation: 4565

You should create new promise in the function to handle reject and resolve not by handling resolve to the function itself. Use then to get the response value from promise. I guess this should work.

var promise = require("promise");
var request = require("request");


function get_login_code()
{
    var promise = new Promise(function(resolve, reject) {
          request.get("someurl.com", function (error, response, body)
          {
             if (error) {
                 reject(error);
             } else {
                 // just for example
                 body = 'TOKEN" value="hello world"';
                 var login_code = body.match(/.TOKEN" value="([^"]+)../i);
                 resolve(login_code);
             }
          });
    });       
}

get_login_code()
        .then(function (code) {
      console.log(code);
});

Upvotes: 1

Related Questions