Search code examples
javascriptcallbackjsdocjscs

Redundant JSDoc @return from an anonymous callback in JavaScript


I am using JSCS with Google preset style rules to check my code and I have a method in a DAO class defined like so:

/**
 * Inserts a new user into database.
 *
 * @param {User} user User to insert.
 * @return {User} Last inserted user.  // Redundant return statement
 * @throws Error if query fails.
 * @since 1.0
 */
add(user) {
  this.pool.getConnection((err, conn) => {
    conn.query('INSERT INTO users SET ?', user, (err, rows) => {
      if (err) {
        throw err;
      }
      conn.release();
      return this.getById(rows.insertId);
    });
  });
}

JSCS marks JSDoc @return tag as redundant because it can't find a return statement inside add(user) function scope, but it actually resides inside the anonymous callback (err, rows) => { ... }.

How can I correctly document that return statement? Is my approach wrong or bad in some way?


Solution

  • add does not return anything, so JSDoc is correct when it tells you that your @return tag is not appropriate. If you refactored your code so that add accepted a callback which is passed the result (as described in How do I return the response from an asynchronous call?), you would end up with

    add(user, resultCallback) {
      this.pool.getConnection((err, conn) => {
        conn.query('INSERT INTO users SET ?', user, (err, rows) => {
          if (err) {
            throw err;
          }
          conn.release();
          resultCallback(this.getById(rows.insertId));
        });
      });
    }
    

    Call this with add(user, result => { ... }) instead of result = add(user).

    How to document this? See How to document callbacks using JSDoc? It would look like:

    /**
     * Inserts a new user into database.
     *
     * @param {User} user User to insert.
     * @param {userResultCallback} resultCallback callback with last inserted user
     * @throws Error if query fails.
     * @since 1.0
    */
    add(user, resultCallback) {
      //...
    }
    
    /**
     * Callback used to get a single User value.
     * @callback userResultCallback
     * @param {User} user Result of the callback
     */
    

    The @callback at the bottom is stand-alone. It defines a type of callback function, which in this case is a callback that accepts a User as its only argument.