1

Coming from the .NET world I am having a hard time consuming documentation for javascript frameworks. I will take "Node.js MongoDB Driver API" as an example. There is a Collection object which has the count() method. Here is the link for it: http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#count

From there I see that count() takes three parameters:

count(query, options, callback)

At first I thought I need to provide all three of them in order to use this method. However, in the example code for this method I see that it sometimes uses only one and sometimes only one parameter:

// Perform a total count command
collection.count(function(err, count) {
  test.equal(null, err);
  test.equal(4, count);

  // Peform a partial account where b=1
  collection.count({b:1}, function(err, count) {
    test.equal(null, err);
    test.equal(1, count);

    db.close();
  });

In the first case it calls count() with only callback parameter while in the second it provides options and callback. There is no example of using all three parameters as stated in the original method description.

My question is how can one know these kind of things? I mean, if there were no examples in this documentation how would I know that would be possible? Also how can I be sure that there are some other possible usages of the method if that is not covered with examples like this?

I know it is perfectly legal to call javascript functions with only some parameters provided and function should be able to handle it based on the implementation. But as a consumer of API I don't want to look into function implementation to figure out what kind of parameter combination I can pass. It feels to me like this documentation is not complete (I took this mongodb driver just as an example but I came across to similar problem with other js framework docs).

Is there some kind of reasoning that I should have when reading javascript documentation, how to think about it when trying to understand API of different frameworks, how to know what is possible and what is not etc...?

2
  • I guess it is just assumed you are familiar with Javascript. If a parameter is not entered into the function it is undefined in the function. If there is more parameters than defined then they are ignored. Except they can be accessed through the arguments variable. It is a lack of documentation if it doesn't specific all of its parameters but I find they always do. Commented Jun 3, 2015 at 14:54
  • For example the count example you gave clearly lists its parameters. And it follows a common design pattern, data/options/callback. e.g coll.count({b:1},{limit:true,skip:false,hint:'derp'},function(err,count){}); Commented Jun 3, 2015 at 15:09

1 Answer 1

2

In JavaScript and specially Node.JS world there is a common pattern on asynchronous functions that their last argument should be a callback function.

count(query, options, callback)

When you call a async function, you must foresee that the result of the call will come in a callback otherwise how could get the results of your async function call? so based on the above statement you should at least provide a callback function to the count method and other async functions that you call in JavaScript.

Another thing that could help you when you see methods of MongoDB is that it is common that if you are going to process some data with the database, you need to provide at least a query object and a callback function but if you need additional information for your query you will provide, the options object.

I know that the documentation is not good explaining if the query and options parameters are optionals but if you see the source code of the count method and read my comments added on the code you could understand:

Collection.prototype.count = function(query, options, callback) {

    // args represents the three parameters
    var args = Array.prototype.slice.call(arguments, 0);

    // extract your last argument and assumes that it is the callback function
    callback = args.pop();

    // extract the first argument that is query
    query = args.length ? args.shift() || {} : {};

    // extract the second argument but this time shift already extracted query
    // so the first parameter this time will be options.
    options = args.length ? args.shift() || {} : {};

    ...
}

if you pass the following values to the call, you will see the order commented in how the count method is going to grab the arguments:

count({}, {}, function callback() {}); // count(query, options, callback)
count({}, function callback() {}); // count(query, callback)
count(function callback() {}); // count(callback)

In fact in your example that you provided in the nested call to count method, you are passing a query and a callback and not options and a callback to the count method:

collection.count(function(err, count) {
  test.equal(null, err);
  test.equal(4, count);

  // You are passing the values in this order (query, callback)
  // {b: 1} === query
  collection.count({b:1}, function(err, count) {
    test.equal(null, err);
    test.equal(1, count);

    db.close();
});

I hope this explanation and code helps you to understand this common pattern of callbacks around JavaScript world.

Sign up to request clarification or add additional context in comments.

Comments

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.