I'm trying to figure out how to comment it correctly using JSDoc3.
/**
* Module ...
*
* #module Cookie
* #returns {{create, get, remove}}
*/
const cookie = (function () {
/**
* Function to create cookie.
*
* #param {String} name - The cookie name.
* #param {String} value - The cookie value.
* #param {Boolean} elongate - The flag to extend cookie lifetime.
*/
const create = (name, value, elongate) => {
...
};
/**
* Function to get cookie.
*
* #param {String} key - The cookie identificatior to get.
* #returns {*}
*/
const get = (key) => {
...
};
/**
* Function to remove cookie.
*
* #param {String} key - The cookie identificator to remove.
*/
const remove = (key) => {
...
};
return {
create: create,
get: get,
remove: remove
}
})();
I'm doing it this way, but generated document looks terrible. I can not rewrite this part of the code to the ES6 standard. Can you please advice?
After some trying ai found #memberof
You can use it like this:
#memberof module:YourModuleName
Do not know, if it is correct, but after that I saw that method is showed in my module doc. page.
I have the following JavaScript.
It is a RequireJS module that has its functions namespaced into an object literal. I referred to: How do I JSDoc A Nested Object's Methods? to find out how to mark up the JSDoc notations.
I run JSDocs 3.3.0-beta3 with private: true in a grunt task but on the modules page there are no private methods or arguments for the publich method.
/**
* A module doing a lot of Foo.
* #module Foo
* #requires jquery
* #author Markus Falk
*/
define(['jquery'], function($) {
'use strict';
/**
* #property {Object} Container
*/
var Foo = {
/**
* Caches all jQuery Objects for later use
* #function
* #private
*/
_cacheElements: function() {
this.$foo = $('.foo');
},
/**
* inits the app and returns the Message Text
* #function
* #public
* #param {Object} msg - The message.
* #param {string} msg.text - The message's Text.
* #param {string} msg.author - The message's author.
* #returns {String} Sentence with given message.text
*/
init: function(msg) {
this._cacheElements();
return "Say " + msg.text;
}
};
return /** #alias module:Foo */ {
/** init */
init: Foo.init
};
});
Here is the output of this JSDoc code:
Try #function init and #function _cacheElements
/**
* A module representing a Foo.
* #module Foo
* #requires jquery
* #author Markus Falk
*/
define(['jquery'], function($) {
'use strict';
/**
* #property {Object} Container
*/
var Foo = {
/**
* Caches all jQuery Objects for later use
* #function _cacheElements
* #private
*/
_cacheElements: function() {
this.$foo = $('.foo');
},
/**
* inits the app and returns the Message Text
* #function init
* #public
* #param {Object} msg - The message.
* #param {string} msg.text - The message's Text.
* #param {string} msg.author - The message's author.
* #returns {String} Sentence with given message.text
*/
init: function(msg) {
this._cacheElements();
return "Say " + msg.text;
}
};
return /** #alias module:Foo */ {
/** init */
init: Foo.init
};
});
If I define an object like this:
/**
* My Cool Object
* #constructor
*/
function MyCoolObject() {
/**
* Cool Method, private
* #param {!string} parameter
*/
function localMethod(parameter) {
// do stuff
}
// Export the method
this.exportedMethod = localMethod;
}
I'd like to know, if at all possible, how to tell JSDOC to use the annotation for localMethod in exportedMethod, or how can I annotate exportedMethod, because if I do:
// Export the method
/**
* Cool Method
* #param {!string} parameter
*/
this.exportedMethod = localMethod;
JSDOC assumes it's a field rather than a method, then only uses the description, ignoring the #param part.
I would reduce it to:
/**
* My Cool Object
* #constructor
*/
function MyCoolObject() {
/**
* Cool Method, private
* #param {!string} parameter
*/
this.exportedMethod = function (parameter) {
// do stuff
};
}
You can do var localMethod = this.exportedMethod right after if you want a local reference to the method. In the off chance that you've over-simplified your example and you need to first assign to localMethod before assigning to this.exportedMethod you could do this:
/**
* My Cool Object
* #constructor
*/
function MyCoolObject() {
function localMethod(parameter) {
// do stuff
}
/**
* Cool Method, private
* #param {!string} parameter
* #function
*/
// Export the method
this.exportedMethod = localMethod;
}
The #function declaration tells jsdoc that it is dealing with a function.
I'm trying to create documentation based on the following structure:
/**
* #ngdoc service
*
* #name module:resource
* #module module
* # return {Object} The returned object
*/
angular.module('module').factory('resource', [
function () {
function Foo (param1) {
//Do something with param1
}
return {
Test: {
/**
* #ngdoc function
* #name resource#theTest
* #methodOf module:resource
*
* #description
* Search to see if a study exists with the given protocol identifier
* #param {Object} params The param
* #return {Object} A Promise
*/
theTest: function(param) {
return functionFoo (param);
},
/**
* #ngdoc function
* #name resource#theTest1
* #methodOf module:resource
*
* #description
* Search to see if a study exists with the given protocol identifier
* #param {Object} params The param
* #return {Object} A Promise
*/
theTest1: function(param) {
return functionFoo (param)
}
}
};
}
]);
What I would like to say in the documentation is that the service 'resource' returns an object that returns a collection of functions, but I cannot find the way of doing this with ngdocs. Is it supported?
Thank you
I don't think you could specify a 'map of function' the only type that are supported are Function, object, string, number, ...
But you could instead add a description in your class like:
/*
* #description
* This class return 2 functions as describe below:
* ```js
* {
* theTest {Function} This function do (...)
* theTest1 {Function} This function do (...)
* };
* ```
*/
function Foo (param1) {
Hope this will help
I've been trying to use JSDoc3 to generate documentation on a file, but I'm having some difficulty. The file (which is a Require.js module) basically looks like this:
define([], function() {
/*
* #exports mystuff/foo
*/
var foo = {
/**
* #member
*/
bar: {
/**
* #method
*/
baz: function() { /*...*/ }
}
};
return foo;
}
The problem is, I can't get baz to show up in the generated documentation. Instead I just get a documentation file for a foo/foo module, which lists a bar member, but bar has no baz (just a link to foo's source code).
I've tried changing bar's directive to #property instead, and I've tried changing baz's directive to #member or #property, but none of that helps. No matter what I do, baz just doesn't seem to want to show up.
Does anyone know what directive structure I could use to get baz to appear in the generated documentation?
P.S. I've tried reading pages like this one on the JSDoc site http://usejsdoc.org/howto-commonjs-modules.html, but it only describes cases of foo.bar, not foo.bar.baz.
You can use a combination of #module or #namespace along with #memberof.
define([], function() {
/**
* A test module foo
* #version 1.0
* #exports mystuff/foo
* #namespace foo
*/
var foo = {
/**
* A method in first level, just for test
* #memberof foo
* #method testFirstLvl
*/
testFirstLvl: function(msg) {},
/**
* Test child object with child namespace
* #memberof foo
* #type {object}
* #namespace foo.bar
*/
bar: {
/**
* A Test Inner method in child namespace
* #memberof foo.bar
* #method baz
*/
baz: function() { /*...*/ }
},
/**
* Test child object without namespace
* #memberof foo
* #type {object}
* #property {method} baz2 A child method as property defination
*/
bar2: {
/**
* A Test Inner method
* #memberof foo.bar2
* #method baz2
*/
baz2: function() { /*...*/ }
},
/**
* Test child object with namespace and property def.
* #memberof foo
* #type {object}
* #namespace foo.bar3
* #property {method} baz3 A child method as property defination
*/
bar3: {
/**
* A Test Inner method in child namespace
* #memberof foo.bar3
* #method baz3
*/
baz3: function() { /*...*/ }
},
/**
* Test child object
* #memberof foo
* #type {object}
* #property {method} baz4 A child method
*/
bar4: {
/**
* The #alias and #memberof! tags force JSDoc to document the
* property as `bar4.baz4` (rather than `baz4`) and to be a member of
* `Data#`. You can link to the property as {#link foo#bar4.baz4}.
* #alias bar4.baz4
* #memberof! foo#
* #method bar4.baz4
*/
baz4: function() { /*...*/ }
}
};
return foo;
});
EDIT as per Comment: (Single page solution for module)
bar4 without that ugly property table. ie #property removed from bar4.
define([], function() {
/**
* A test module foo
* #version 1.0
* #exports mystuff/foo
* #namespace foo
*/
var foo = {
/**
* A method in first level, just for test
* #memberof foo
* #method testFirstLvl
*/
testFirstLvl: function(msg) {},
/**
* Test child object
* #memberof foo
* #type {object}
*/
bar4: {
/**
* The #alias and #memberof! tags force JSDoc to document the
* property as `bar4.baz4` (rather than `baz4`) and to be a member of
* `Data#`. You can link to the property as {#link foo#bar4.baz4}.
* #alias bar4.baz4
* #memberof! foo#
* #method bar4.baz4
*/
baz4: function() { /*...*/ },
/**
* #memberof! for a memeber
* #alias bar4.test
* #memberof! foo#
* #member bar4.test
*/
test : true
}
};
return foo;
});
References -
Another Question about nested namespaces
For alternative way of using Namespaces
Documenting literal objects
*Note I haven't tried it myself. Please try and share the results.
Here's a simple way to do it:
/**
* #module mystuff/foo
* #version 1.0
*/
define([], function() {
/** #lends module:mystuff/foo */
var foo = {
/**
* A method in first level, just for test
*/
testFirstLvl: function(msg) {},
/**
* #namespace
*/
bar4: {
/**
* This is the description for baz4.
*/
baz4: function() { /*...*/ },
/**
* This is the description for test.
*/
test : true
}
};
return foo;
});
Note that jsdoc can infer the types baz4.baz4 and test without having to say #method and #member.
As far as having jsdoc3 put documentation for classes and namespaces on the same page as the module that defines them, I don't know how to do it.
I've been using jsdoc3 for months, documenting a small library and a large application with it. I prefer to bend to jsdoc3's will in some areas than have to type reams of #-directives to bend it to my will.
You can't document nested functions directly. I didn't like Prongs solution, so I used a different implementation without namespaces (it's JS, not Java!).
Update:
I updated my answer to reflect the exact use case given by the OP (which is fair, since JSdoc is pretty painful to use). Here is how it would work:
/** #module foobar */
/** #function */
function foobarbaz() {
/*
* You can't document properties inside a function as members, like you
* can for classes. In Javascript, functions are first-class objects. The
* workaround is to make it a #memberof it's closest parent (the module).
* manually linking it to the function using (see: {#link ...}), and giving
* it a #name.
*/
/**
* Foo object (see: {#link module:foobar~foobarbaz})
* #name foo
* #inner
* #private
* #memberof module:foobar
* #property {Object} foo - The foo object
* #property {Object} foo.bar - The bar object
* #property {function} foo.bar.baz - The baz function
*/
var foo = {
/*
* You can follow the same steps that was done for foo, with bar. Or if the
* #property description of foo.bar is enough, leave this alone.
*/
bar: {
/*
* Like the limitation with the foo object, you can only document members
* of #classes. Here I used the same technique as foo, except with baz.
*/
/**
* Baz function (see: {#link module:foobar~foo})
* #function
* #memberof module:foobar
* #returns {string} Some string
*/
baz: function() { /*...*/ }
}
};
return foo;
}
Unfortunately JSdoc is a port of Java, so it has a lot of features that make sense for Java but not for JS, and vice-versa. For example, since in JS functions are first-class objects, they can be treated as objects or functions. So doing something like this should work:
/** #function */
function hello() {
/** #member {Object} */
var hi = {};
}
But it won't, because JSdoc recognizes it as a function. You would have to use namespaces, my technique with #link, or to make it a class:
/** #class */
function Hello() {
/** #member {Object} */
var hi = {};
}
But then that doesn't make sense either. Do classes exist in JS? no, they don't.
I think we really need to find a better documentation solution. I've even seen inconsistencies in the documentation for with how types should be displayed (e.g. {object} vs {Object}).
You can also use my technique to document closures.
Just to improve on Prongs's answer a bit for JSDoc3, I was only able to get it to work when I used the #instance annotation in lieu of #member.
ES6 example code follows:
class Test
{
/**
* #param {object} something
*/
constructor(something)
{
this.somethingElse = something;
/**
* This sub-object contains all sub-class functionality.
*
* #type {object}
*/
this.topology = {
/**
* Informative comment here!
*
* #alias topology.toJSON
* #memberof! Test#
* #instance topology.toJSON
*
* #returns {object} JSON object
*/
toJSON()
{
return deepclone(privatesMap.get(this).innerJSON);
},
...
}
}
}