Search code examples
javascriptnode.jsstringweb-scraping

Returning a concatenated string from callback nodejs


Hi I'm new to nodejs and I'm having trouble with returning a string of lyrics from metrolyrics.com. The lyrics are stored in separate paragraphs and I'm trying to return a string with all the paragraphs connected. I looked up some resources online and saw that I had to use a callback function, but I don't think I am doing it properly. Here's the code I have so far:

var request = require('request');
var cheerio = require('cheerio');

function getLyrics(artistName, songTitle, fn) {
    var lyric = "";
    var url = 'http://www.metrolyrics.com/' + songTitle.toLowerCase().replace(/ /g, "-")+ "-lyrics-" + artistName.toLowerCase().replace(/ /g, "-") + ".html";
    request(url, function(err, resp, body){
        if(err) {
            throw err;
        }
        $ = cheerio.load(body);
        $('#lyrics-body-text p').each(function(){
            lyric += $(this).text();
        });
    }); 
    return fn(lyric);
}

getLyrics('John Legend', 'All of Me', function(result) {console.log(result)});

Solution

  • var request = require('request');
    var cheerio = require('cheerio');
    
    function getLyrics(artistName, songTitle, fn) {
        var lyric = "";
        var url = 'http://www.metrolyrics.com/' + songTitle.toLowerCase().replace(/ /g, "-")+ "-lyrics-" + artistName.toLowerCase().replace(/ /g, "-") + ".html";
        request(url, function(err, resp, body){
            if(err) {
                throw err;
            }
            $ = cheerio.load(body);
            $('#lyrics-body-text p').each(function(){
                lyric += $(this).text();
            });
            return fn(lyric); // You should call your callback inside request callback, because it's an async operation
        }); 
    }
    
    getLyrics('John Legend', 'All of Me', function(result) {console.log(result)});
    

    Otherwise, return is executed instantly, before request is done and its callback executed.