Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "TypeError: Right-hand side of 'instanceof' is not callable" when I use another module class?

I tried to check the type of context whether it is an instance of Context, which is in another file, but node js throws TypeError: Right-hand side of 'instanceof' is not callable.

index.js

const Transaction = require('./Transaction');

class Context {
    constructor(uid) {
        if (typeof uid !== 'string')
            throw new TypeError('uid must be a string.');

        this.uid = uid;
    }

    runTransaction(operator) {
        return new Promise((resolve, reject) => {
            if (typeof operator !== 'function')
                throw new TypeError('operator must be a function containing transaction.');

            operator(new Transaction(this))
        });
    }
}

module.exports = Context;

Transaction.js

const Context = require('./index');

class Transaction {
    constructor(context) {
        // check type
        if (!(context instanceof Context))
            throw new TypeError('context should be type of Context.');

        this.context = context;
        this.operationList = [];
    }

    addOperation(operation) {

    }
}

module.exports = Transaction;

Another js file

let context = new Context('some uid');
context.runTransaction((transaction) => {
});

And there, it throws TypeError: Right-hand side of 'instanceof' is not callable.

like image 269
Danny Zhao Avatar asked Jun 21 '19 05:06

Danny Zhao


1 Answers

The problem is that you have a circular dependency. The other file requires index, index requires Transaction, and Transaction requires index. So, when transaction runs, it tries to require index, whose module is already in the process of being built. index hasn't exported anything yet, so requiring it at that time results in an empty object.

Because both must call each other, one way to solve it would be to put both classes together, and export them both:

// index.js
class Context {
  constructor(uid) {
    if (typeof uid !== "string") throw new TypeError("uid must be a string.");

    this.uid = uid;
  }

  runTransaction(operator) {
    return new Promise((resolve, reject) => {
      if (typeof operator !== "function")
        throw new TypeError(
          "operator must be a function containing transaction."
        );

      operator(new Transaction(this));
    });
  }
}

class Transaction {
  constructor(context) {
    // check type
    if (!(context instanceof Context))
      throw new TypeError("context should be type of Context.");

    this.context = context;
    this.operationList = [];
    console.log("successfully constructed transaction");
  }

  addOperation(operation) {}
}

module.exports = { Context, Transaction };

and

const { Context, Transaction } = require("./index");
const context = new Context("some uid");
context.runTransaction(transaction => {});

https://codesandbox.io/s/naughty-jones-xi1q4

like image 198
Snow Avatar answered Oct 17 '22 22:10

Snow