Day 99 - Mongoose + async act up to create cocktail

I found another really strange thing that happens with Mongoose when used inside Async.

let mongoose = require('mongoose');
mongoose.connect(db_conn_string);

let util = require('util');
let async = require('async');
let Schema = mongoose.Schema;
let ObjectId = Schema.ObjectId;

var PersonSchema = new Schema({
  name: {
    type: String
  },
  username: {
    type: String,
    required: true,
  }
});

var Person = mongoose.model('Person', PersonSchema);

var p1 = new Person({ username: "u" + Math.random(), name: "User 8" });
var p2 = new Person({ username: "u4" + Math.random(), name: "User 10" });

async.auto({
  other: (callback) => p1.save(callback),
  normal: (callback) => p2.save(function (error, created) {
    if (error) {
      callback(error);
    } else {
      callback(null, created);
    }
  })
}, function (error, results) {
  console.log(require('util').inspect(results, { depth: null }));
  process.exit(1);
});

This code gives the following output:

{ other: 
   [ { __v: 0,
       username: 'u0.16941186863323354',
       name: 'User 8',
       _id: 5929cc51d66b3e0a4c4796f0 },
     1 ],
  normal: 
   { __v: 0,
     username: 'u40.00008901152893536768',
     name: 'User 10',
     _id: 5929cc51d66b3e0a4c4796f1 } }

If you have not noticed the inconsistency yet, see the results again. Two apparently same blocks of code seem to be doing something completely different. One returns an object while the other returns an array containing an object and an integer. (On further investigation, I found out that the number is the number of people that were created. If you do p1.save(...) and then again p1.save(...), the count turns out to be 0)

Now, other is the new function notation that has been activated in ES 2015. I have read the syntax documentation for this and nothing seems amiss here.

Trying this out without async, using code that looks like this:

// Mongoose connection, Person schema, Person model declaration etc

function genPerson({ username, name }, done) {
  let p1 = new Person({ username, name });
  p1.save(done);
}

genPerson({ username: "u" + Math.random(), name: "User" }, (error, created) => {
  if (error) {
    console.error(error);
    process.exit(1);
  } else {
    console.log(created);
    process.exit(0);
  }
});

Inside of this, created is the object that was created an NOT the array that is returned in the previous code’s other case.

A very intriguing issue that has now been put out there in the public for people to find and explain. This undoubtedly restricts the usage of the arrow syntax with async unless you would like to have random [0]s everywhere in your results.objName[0] references.

POST #99 is OVER

P.S. 99 posts are OVER! YAY YAY YAY! One more post to go tomorrow and I would have finally completed 100 posts in 100 days. More or less writing daily.