1

I am learning Node JS and I am learning how to create OOP structure in node. I have a simple class where I am using functions to check and create user in database. I am getting TypeError when I am calling class function inside a function. My codes of class,

var method = AccessRegisterAction.prototype;

function AccessRegisterAction(parameters) {

    this._bcrypt = require('bcrypt-nodejs');
    this._cassandra = require('cassandra-driver');
    this._async = require('async');


    this._uname = parameters.uname;
    this._email = parameters.email;
    this._passwd = parameters.passwd;

    //Connect to the cluster
    this._client = new this._cassandra.Client({contactPoints: ['127.0.0.1'], keyspace: 'testdb'});

    //this._bcrypt.hashSync("bacon");

}

/*
 * This method "createUser" is used to create new users
 *
 * First it will check for user's email is in database or not.
 *
 * If email is registered we will process accordingly,
 * else we will process accordingly.
 *
 * */

method.createUser = function () {
    var selectUserFromDBQuery = "SELECT uid from testdb.users WHERE email = '?' ALLOW FILTERING";

    this._client.execute(selectUserFromDBQuery, this._email, function (err, result) {

        //if there is not any error while fetching data
        if (!err) {

            //if there is result, it means we have email already registered
            if (result.rows.length > 0) {

                //so now we need to show user is already registered error
                //to the user
                this.errorWhileCreatingAccount(2);

            } else {

                //here we are checking user's username because
                //we have not found user's email in database and we
                //are good to go to register user
                this.userNameCheck();


            }
        }
        else {
            this.errorWhileCreatingAccount(1);
        }

    });
};


/*
 * This method will check for username in database.
 *
 * If there is username registered in database than we will
 * show error that username is taken otherwise
 * we will process to register user.
 * */
method.userNameCheck = function () {
    var checkUserNameQuery = "SELECT uid from testdb.users WHERE uname = '?' ALLOW FILTERING";

    this._client.execute(checkUserNameQuery, this._uname, function (err, result) {

        //if there is not any error while fetching data
        if (!err) {

            //if there is result, it means we have email already registered
            if (result.rows.length > 0) {

                //so username is taken and we need to tell user to
                //use different username
                this.errorWhileCreatingAccount(3);

            } else {

                //here we are registering user and adding information into database
                this.newUserCreate();

            }
        }
        else {
            this.errorWhileCreatingAccount(1);
        }

    });

};

/*
 * This method will create new user into database
 *
 * Simple as that
 * */
method.newUserCreate = function () {
};


/*
 * This function will throw an error which was occurred during the account creation process
 * */
method.errorWhileCreatingAccount = function (errorCode) {
    var _error = {error: "", msg: ""};

    switch (errorCode) {
        case 1:
            _error.error = true;
            _error.msg = "There was error while checking your information. Please try again.";
            break;
        case 2:
            _error.error = true;
            _error.msg = "You have already created account with this email. " +
                "Please use forgot password link if you don't remember your login details.";
            break;
        case 3:
            _error.error = true;
            _error.msg = "Username that you chose is already taken. Please try different username.";
            break;
        default:
            _error.error = true;
            _error.msg = "There was error an error. Please try again.";
            break
    }

};


// export the class
module.exports = AccessRegisterAction;

And the error message I am getting is,

events.js:160
      throw er; // Unhandled 'error' event
      ^

TypeError: this.userNameCheck is not a function
    at /Users/user/Desktop/Projects/nodejs/testproject/application/classes/UserAccessAction/AccessRegisterAction.js:55:22
    at next (/Users/user/node_modules/cassandra-driver/lib/utils.js:616:14)
    at readCallback (/Users/user/node_modules/cassandra-driver/lib/request-handler.js:202:5)
    at Connection.invokeCallback (/Users/user/node_modules/cassandra-driver/lib/connection.js:584:5)
    at Connection.handleResult (/Users/user/node_modules/cassandra-driver/lib/connection.js:522:8)
    at emitThree (events.js:116:13)
    at ResultEmitter.emit (events.js:194:7)
    at ResultEmitter.each (/Users/user/node_modules/cassandra-driver/lib/streams.js:482:17)
    at ResultEmitter._write (/Users/user/node_modules/cassandra-driver/lib/streams.js:466:10)
    at doWrite (_stream_writable.js:307:12)

and my codes where I calling this function is,

var param = {uname: "testname", email: "[email protected]", passwd: "test123"};
    var AccessRegisterAction = require('../application/classes/UserAccessAction/AccessRegisterAction');
    var register = new AccessRegisterAction(param);
    register.createUser();

so can anyone tell me where my mistake is? How can I use oop with nodejs?

Thanks

2
  • 1
    When you call this.userNameCheck(); it's using the wrong this. You are calling it within a different function, so the context is not pointing to your class. Commented Sep 1, 2016 at 20:10
  • So how can I use it without this to call the function? Commented Sep 1, 2016 at 20:35

2 Answers 2

2

Since it looks like you're using ES5 style, I'm not going to recommend arrow functions. However, as was brought out in the comments, the value of this changes inside each function statement. So, you need to save the context you'd like to use before entering the inner functions. For example:

method.createUser = function () {
    var context = this;
    var selectUserFromDBQuery = "SELECT uid from testdb.users WHERE email = '?' ALLOW FILTERING";

    this._client.execute(selectUserFromDBQuery, this._email, function (err, result) {

    //if there is not any error while fetching data
    if (!err) {

        //if there is result, it means we have email already registered
        if (result.rows.length > 0) {

            //so now we need to show user is already registered error
            //to the user
            context.errorWhileCreatingAccount(2);

        } else {

            //here we are checking user's username because
            //we have not found user's email in database and we
            //are good to go to register user
            context.userNameCheck();


        }
    }
    else {
            context.errorWhileCreatingAccount(1);
        }

    });
};

Do this in each method which attempts to call this from within a new function.

Sign up to request clarification or add additional context in comments.

Comments

0

You should be able to use prototypes easily enough in Node You need to use an object first eg new AccessRegisterAction(), you'd be able to use the methods as usual.

It's hard to be sure as you've not posted the code you are using to access the method.

1 Comment

Thank you for your help. But answer from @Amleonard worked for me,

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.