Exploring the concept of callbacks when using the http.get function in node

As a new node programmer, I am struggling to grasp how to retrieve the contents of an HTTP request from a function due to the asynchronous nature of node. Below is a simplified version of my program:

//#1
function getWebsiteData(url) {
    var body;
    http.get(url, function (res) {
        res.on('data', function (chunk) {
            body += chunk;
            //***At this point, I need 'body' to be returned from this function***
        });
    });
}


//#2
var dataA = getWebsiteData('website1.com');
var dataB = getWebsiteData('website2.com');

//#3
console.log(dataA + dataB);

My goal is simple: 1: create a function that retrieves data from a site (specifically JSON and XML), 2: call that function from any part of my program, 3: manipulate the data returned by the function.

The placement and calling of callback functions in node.js are causing me quite a headache. Despite studying numerous examples of http.get and callbacks, I have not been able to find one where they mesh together like in my sample code. After a full day of unsuccessful attempts, I am hopeful that seeing how to implement this in my example will finally make it click in my mind (fingers crossed).

Answer №1

Here is the fundamental pattern to follow for using plain callback style:

function fetchWebsiteData(url, callback) {
    let content = "";
    http.get(url, function (response) {
        response.on('data', function (chunk) {
            content += chunk.toString();
            // Returning a value from this function won't work
            // The return value will be consumed by the function
            // that calls this function, which is internal Node.js code
        });
        response.on("end", function() {
          callback(null, content)
        })
        response.on("error" function(error) {
          callback(error)
        })
    });
}

fetchWebsiteData("a", function(error, dataA) {
  if (error) throw "Error fetching website A."
  fetchWebsiteData("b", function(error, dataB) {
    if (error) throw "Error fetching website B."
    console.log(dataA)
    console.log(dataB)
  })
})

You might also consider utilizing flow-control libraries like Async (or my promise-based Faithful), or general-purpose promise libraries like RSVP.js. I suggest getting familiar with callbacks basics first.

For simple http requests, it's more convenient to use the request module. No need to attach event listeners. Just a function similar to the fetchWebsiteData function (which has its own issues!).

To grasp async programming, try reading and writing files with fs.readFile and fs.writeFile. Attempt something like writing contents of file A to file B. These are simpler functions, but you must manage callback flow correctly. Node's http module is comparatively complex. You can opt for the request module as an alternative.

Answer №2

Before the data is returned, you're calling console.log(). To fix this issue, consider bringing the body variable to a higher scope and appending to that instead.

let body;

function fetchWebsiteData(url) {
    http.get(url, function (res) {

        res.on('data', function (chunk) {
            body += chunk;
            //***At this point, I require 'body' to be returned outside of this function***
            displayBody(body);
        });
    });
}
let siteOne = fetchWebsiteData('website1.com');
let siteTwo = fetchWebsiteData('website2.com');

function displayBody(value){
    console.log(value);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using ReactJS to strip HTML tags from JSON response

I'm having trouble figuring out how to strip HTML tags from a JSON response in reactjs. Here's the JSON response: { "price": "26,800.98", "diff": "<!--daily_changing-->+13.44 (+0.05%)&nbsp;& ...

When working with ng-show and ng-hide in AngularJS, I noticed a brief 1ms delay where both objects are still

I am encountering a similar issue as discussed in the following post: How to use ng-show and ng-hide with buttons in AngularJS In my case, I have play/pause buttons where the ng-show/hide functionality is working. However, the problem lies in the fact tha ...

Divergent behavior of jQuery AJAX when used with a standard form versus when called in a popup within a div

Why does the jQuery AJAX work perfectly when submitting a form using the normal method, but not when submitting the same form within a popup? Below is the code for reference. Form submission script: $("#submit").click(function (e) { /* $('form&a ...

spinning div content in a manner reminiscent of a roulette wheel

I am looking to create a roulette game that randomly selects numbers and displays them. Initially, I attempted to use images and backgroundOffset, but it caused significant lagging issues and difficulty in checking the rolled number. Therefore, I have impl ...

Using a JavaScript onclick function to retrieve specific elements within the document

I'm attempting to extract the elements from the source that was clicked on, but for some reason it's not functioning correctly. Check out my JSFIDDLE Here's the HTML: <span class="populate" onclick="populate();" href="?id=1">Hello&l ...

What is the best way to transfer a multidimensional array from PHP to JavaScript?

Attempting to extract array value from a JSON string, I utilize the json_decode function in PHP. <?php $jsonContent=file_get_contents('http://megarkarsa.com/gpsjson.php'); $jsonDecoded=json_decode($jsonContent,true); foreach($jsonEncoded[&apo ...

Trouble concealing tab using slideUp function in Jquery

Whenever I click on the 'a' tag, it displays additional HTML content (list) that is controlled by generic JS code for tabs. However, I want to hide the list when I click on the "Title" link again. What can I do to achieve this? You can view a de ...

Extract a selection from a dropdown menu in ReactJS

I have multiple cards displayed on my screen, each showing either "Popular", "Latest", or "Old". These values are retrieved from the backend. I have successfully implemented a filter option to sort these cards based on popularity, age, etc. However, I am u ...

Display TMX Map on Three.js Plane

Updated question with new code I'm currently working on a WebGL shader that is designed to render a TMX Layer exported from the Tiled editor. My approach involves using THREE.js to create a Plane mesh and setting the material as ShaderMaterial to dra ...

Discover the element's selector for the event that was triggered using jQuery

In the process of creating a lightweight real-time application, we are utilizing jQuery's event system to facilitate communication between modules. Any changes made in the DOM that affect elements outside the module are achieved through triggering eve ...

Is there a method to add HTML code statically rather than in a dynamic environment?

I'm currently in the process of developing a front-end website with no backend code, as I plan to host it on GitHub pages. I feel that adding any additional backend functionality would be unnecessary. Is there a simple method to incorporate common el ...

There seems to be an issue with Bookshelfjs and bcrypt hashPassword - it is functioning properly during the create

When using bcrypt to hash passwords in bookshelfjs, I encountered an issue where the password was not being hashed when attempting to update it. Here is the code snippet: model.js var Bookshelf = require('../../db').bookshelf; var bcrypt = requ ...

Python raises a KeyError if JQuery is included

I have encountered an issue with the code snippet below, where I am attempting to define a variable within the HTML. Oddly enough, when I exclude the JQuery script, everything functions as expected. However, upon reintroducing the JQuery script, the functi ...

Issue: Unidentified supplier following JavaScript compression

Here is the AngularJS controller code that I am working with: (function() { 'use strict'; angular .module('app') .controller('TemplateCtrl', TemplateCtrl); function TemplateCtrl($http, $auth, $rootS ...

What is the best method for extracting data from websites that do not provide plain HTML output?

I have some experience using requests and BeautifulSoup in Python to scrape basic websites, but I've noticed that most modern sites don't just serve up HTML. It seems like they might be running JavaScript or something else (I'm a bit of a ne ...

The versatility of Protractor's variable scope when working with promises

Insight into Angular App Testing As I delved into testing my Angular app using ng-repeat to create a table, a user brought to my attention the presence of duplicate entries. Eager to address this issue, I visually confirmed it and proceeded to craft a Pro ...

What is the best way to delete a particular item from a local storage array in AngularJS?

This is the HTML code I have: <tr ng-repeat="student in students track by $index"> //some code here <button ng-click="remove(student)">Delete</button> </td> </tr> Then, in my .js ...

Can you point me to the location where the 'req' parameter is specified?

I've been exploring a new authentication approach detailed in this article. One issue I'm encountering is locating where the req parameter is declared in the snippet below. It seems like my code won't compile because this parameter isn&apos ...

Ionic 5 page div within ion-contents element is experiencing scrolling issues on iPhone devices

My application features a div element containing an ion-slides component. The ion-slides component houses several ion-slide elements that slide horizontally. Here is the relevant code snippet: <ion-content [scrollEvents]="true"> <div ...

Utilize tween.js to create dynamic color animations in Three.js

var color="#FF0000"; function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)} function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)} function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)} function cutHex(h) {return (h.c ...