0

I have a list of tags that I need to extract. the list is called list.

I'm trying to find all 'og:*' meta that correspond to the list and are available in a fetched html. Then I need to return a hash to the user in JSON that contains these meta tags. But the process method return undefined rather than the hash.

var http = require('http');
var url = require('url');
var request = require('request');
var jsdom = require("jsdom");
var fs = require('fs');
var cssom = require('cssom');

var list = ['title', 'description']; //here the og-tags I need to extract
var meta = {};

function process(url) {
  request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {  
      jsdom.env({
        html: body,
        scripts: [
          'http://code.jquery.com/jquery-1.5.min.js'
        ],
        done: function(errors, window) {
          var $ = window.$;

          $('meta[property^="og:"]').each(function() {
            for (var element in list) {
              if ($(this).attr('property') == 'og:' + list[element]) {
                meta[list[element]] = $(this).attr('content');

                // this works well, if I do console.log(meta), I get the hash correctly filled.
              }
            }
          });
        }
      });
    }
  });

  return meta; // this is where the probleme is. This return undefined.
}


http.createServer(function (request, response) {
  request.setEncoding('utf8');
  response.writeHead(200, {'Content-Type': 'text/plain'});

  process(url.parse(request.url, true).query['content'], function(result) {
    console.log(result); // prints no result
  });

  response.end();
}).listen(8124);

console.log('Server running at http://0.0.0.0:8124');
1
  • 2
    Try not to use process as the name of that function, it's a NodeJS variable through which you can access information related to the node process itself. API Link Commented Aug 20, 2012 at 20:39

1 Answer 1

1

Because request is asynchronous, you need to make process asynchronous as well. That means having process accept a callback parameter that it will call once meta is available. As it is now, process is returning meta before the request callback populates it.

function process(url, callback) {
  request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {  
      jsdom.env({
        html: body,
        scripts: [
          'http://code.jquery.com/jquery-1.5.min.js'
        ],
        done: function(errors, window) {
          var $ = window.$;

          $('meta[property^="og:"]').each(function() {
            for (var element in list) {
              if ($(this).attr('property') == 'og:' + list[element]) {
                meta[list[element]] = $(this).attr('content');
                callback(null, meta);
              }
            }
          });
        }
      });
    } else {
      callback(error);
    }
  });
}


http.createServer(function (request, response) {
  request.setEncoding('utf8');
  response.writeHead(200, {'Content-Type': 'text/plain'});

  process(url.parse(request.url, true).query['content'], function(error, result) {
    console.log(result); // prints no result
  });

  response.end();
}).listen(8124);
Sign up to request clarification or add additional context in comments.

2 Comments

@JohnyHK, a subsidiary question if I may: does request() return a promise, like $.ajax() in client-side jQuery?
@Beetroot-Beetroot Not to my knowledge, no. See the docs here: github.com/mikeal/request

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.