Jose Rojas
Jose Rojas

Reputation: 3530

Script work in a browser but not in NodeJS

I'm struggling trying to understand why this script works perfectly in the browser but not in Node.js in the server.

data = [{"stars": 3}, {"stars": 2}]

var ParseParameter = function(){
    this.parser = "";
}

ParseParameter.prototype = {
    setStrategy: function(parser) {
        this.parser = parser;
    },
 
    parse: function(parameter) {
        return this.parser.parse(parameter);
    }
};


var IntegerParser = function(filter){

    this.parameter = '';
    this.filter = filter;

    this.parse = function(parameter){
        this.parameter = parseInt(parameter); 
    }

    this.filterBy = function(item){
        return item[this.filter] == this.parameter;
    }
}

var filter = 'stars',
    parameter = '2',
    parseParameter = new ParseParameter();

var integerParser = new IntegerParser(filter);
    parseParameter.setStrategy(integerParser);
    parseParameter.parse(parameter);
    
    var dataFiltered = data.filter(parseParameter.parser.filterBy);

    console.log(dataFiltered);

At the server, I print in console the values of this.parameter and this.filter at the function filterBy and these are undefined

I'm running on Node.js version 8.11.2

Any advice will be appreciated.

Upvotes: 1

Views: 104

Answers (1)

Farhan Tahir
Farhan Tahir

Reputation: 2144

The is may be due to problem of this keyword in your script. Inside an inner function this refers to window or global object. For example,

Inside the following code, this.filter of this.filterBy is not referring to the filter property that exists inside the scope of IntegerParser function instead it is referring the variable being defined as var filter = 'stars'. Change this name to something else and you'll see undefined and it won't work on browser as well. That's what could be your issue.

var IntegerParser = function(filter){

    this.parameter = '';
    this.filter = filter;

    this.parse = function(parameter){
        this.parameter = parseInt(parameter); 
    }

    this.filterBy = function(item){
        return item[this.filter] == this.parameter;
    }
}

Instead of using this you could use a known solution for this problem by storing this to a variable for later usage. like in following example:

var IntegerParser = function(filter){

        this.parameter = '';
        this.filter = filter;
        var self = this;  // store this to self and use self in inner functions

        this.parse = function(parameter){
            self.parameter = parseInt(parameter); 
        }

        this.filterBy = function(item){
            return item[self.filter] == self.parameter;
        }
    }

Your entire code including my solution is as follow:

data = [{"stars": 3}, {"stars": 2}]

var ParseParameter = function(){
    this.parser = "";
}

ParseParameter.prototype = {
    setStrategy: function(parser) {
        this.parser = parser;
    },
 
    parse: function(parameter) {
        return this.parser.parse(parameter);
    }
};


var IntegerParser = function(filter){

    this.parameter = '';
    this.filter = filter;
    var self = this;

    this.parse = function(parameter){
        self.parameter = parseInt(parameter); 
    }

    this.filterBy = function(item){        
        return item[self.filter] == self.parameter;
    }
}
var filter = 'stars',
    parameter = '2',
    parseParameter = new ParseParameter();

var integerParser = new IntegerParser(filter);
    parseParameter.setStrategy(integerParser);
    parseParameter.parse(parameter);
    
    var dataFiltered = data.filter(parseParameter.parser.filterBy);

    console.log(dataFiltered);

It should work without any problem. Please try and see if it works for you.

Upvotes: 3

Related Questions