Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coffeescript and node.js confusion. require instantiates class?

I'm having trouble trying to get my class working in my node.js file. When I require the module I wrote, the require './module' calls my constructor and gives an error. But I actually want to instantiate later on in the file.

i.e

class Mic

constructor: (x) ->
  @t = []
  @t.push x

exports.Mic = Mic

and here is my app.coffee file

require 'coffee-script'
require './Mic'

When I run app.coffee it gives an exception ReferenceError: x is not defined. Which makes sense since its calling the constructor, but why is it calling the constructor even though I havent called new Mic ?

Edit After fixing the indentation

class Mic
    constructor: (x) ->
        @t = []
        @t.push x

exports.Mic = Mic

and updating my app.coffee to

Mic = require './Mic'

m = new Mic 3
console.log m

I get the error

TypeError: object is not a function
    at Object.CALL_NON_FUNCTION_AS_CONSTRUCTOR (native)
like image 300
Faisal Abid Avatar asked May 27 '12 06:05

Faisal Abid


1 Answers

First thing's first: you don't need the require 'coffee-script'—running it with coffee is enough; same as running the compiled JavaScript. You don't need the CoffeeScript library available at runtime in your program.

Secondly, the first file appears indented incorrectly; if you want that to be Mic's constructor, indent it one level underneath the class, i.e.:

class Mic
  constructor: (x) ->
    @t = []
    @t.push x

exports.Mic = Mic

Finally, the issue is that exports is an object of exports. See here:

exports.Mic = Mic

You've assigned Mic to the exports object's Mic key, so now exports in Mic.coffee looks like this:

{ Mic: ...your class... }

When you say require './Mic', you're getting that object back; in other words:

require('./Mic') == { Mic: ...your class... }

So you need to do one of the following:

  1. Export Mic as the entire export of Mic.coffee, and not as a key:

    module.exports = Mic
    
  2. Get the entire module out, and then instantiate the Mic object within:

    mic = require './Mic'
    m = new mic.Mic 3
    
  3. Just take Mic out from the require'd module:

    {Mic} = require './Mic'  # equivalent to saying Mic = require('./Mic').Mic
    m = new Mic 3
    
like image 185
Asherah Avatar answered Sep 18 '22 20:09

Asherah