1

I want to save two Mongoose objects in my mocha test - and be notified when both have succeeded. I am using the asyncjs library to achieve this.

beforeEach (done) ->

  obj1 = new Person({ name: 'Jon' })
  obj2 = new Person({ name: 'Dan' })

  console.log obj1   # ... { name: 'Jon', _id: 4534534543512 }

  async.list([
    obj1.save
    obj2.save
  ]).call().end( (err, res) ->
    return done(err) if err
    done()
  )

You can see that obj1 is being set to a MongoDB document in the console.log - but when I want to persist them to the db using the save function, I get the following error when trying to execute this:

TypeError: Cannot read property 'save' of undefined

If I were to replace the two functions in the async.list with say

console.log
console.log

The code executes fine ... Also, if I were to save the two objects outside the async.list function like so

obj1.save()
obj2.save()

It too executes fine with no errors.

I am stumped.

1
  • 1
    Also worth noting, is that there are two similarly named async libraries: async, and asyncjs. The above example is from asyncjs - but the better library is async, and the method to use there instead is: parallel. Commented Apr 5, 2013 at 6:46

1 Answer 1

2

It's likely because the save functions aren't being called with a expected context (this).

When you pass a "method" like obj1.save, the reference async.list() gets is only to the function itself without any link back to obj1 (or obj2). It would be similar to:

save = obj1.save
save() # `this` is `undefined` or `global`

To pass with a fixed context, you can either bind them:

async.list([
  obj1.save.bind(obj1)
  obj2.save.bind(obj2)
]) # etc.

Or use additional functions so they're called after a member operator:

async.list([
  (done) -> obj1.save(done),
  (done) -> obj2.save(done)
]) # etc.
Sign up to request clarification or add additional context in comments.

1 Comment

That did the trick - thank you - you put an end to a lot of frustration. I suspected something around this - and passed this in via the call method - and called this.obj1.save(), which clearly didn't work.

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.