Ritvik Joshi
Ritvik Joshi

Reputation: 95

Why is closure property not working in nodejs?

I am new to node js and taking a course to learn it. However, I am not able to make a simple closure property of javascript work in it. I have 2 files index.js and rectangle.js where in I am using callback to return the area & perimeter of rectangle.

index.js

var rect = require('./rectangle');

function solveRect(l,b) {
    console.log("Solving for rectangle with l = " + l + "and b = " + b);

    rect(l,b, (err,rectangle) => {
        if(err) {
            console.log("ERROR: " + err.message);
        }
        else {
            console.log("The area of rectangle of dimensions l = " 
                + l + "and b = " + b + " is "  + rectangle.area());

            console.log("The perimeter of rectangle of dimensions l = " 
                + l + "and b = " + b + " is "  + rectangle.perimeter());
        }
    });
    console.log("This statement is after the call to rect()");
}

solveRect(2,4);
solveRect(3,5);
solveRect(0,4);
solveRect(-3,-5);

rectangle.js

module.exports = (x,y,callback) => {
    if( x <= 0 || y <= 0) {
        setTimeout(() =>
            callback(new Error("rectangle dimensions should be greater than zero"),
                null),
            2000
        );
    }
    else {
        setTimeout(() =>
            callback(null,
                {
                    perimeter: (x,y) => (2*(x+y)),
                    area: (x,y) => (x*y)
                }),
            2000
        );
    }
}

I see that since length and breadth are already available to the callback from the outer scope, there isn't any need to pass them when we call the rectangle.area() function.

Output: I get NaN returned as area and perimeter and not the actual calculated area.

Upvotes: 0

Views: 122

Answers (1)

Barmar
Barmar

Reputation: 781068

The perimiter and area functions take arguments x and y, so they use those arguments to calculate the results, not the variables inherited from the closure. Since you're not supplying any arguments when you call them in solveRect(), you're performing arithmetic on undefined, which results in NaN.

Get rid of the arguments so they'll use the closure variables.

        setTimeout(() =>
            callback(null,
                {
                    perimeter: () => (2*(x+y)),
                    area: () => (x*y)
                }),
            2000
        );

Upvotes: 2

Related Questions