I'm writing documentation with yuidoc. However, I have a class Model, which has one of its methods defined elsewhere. Here is some code to visualize the situation.
Assume I have a file model.js:
/**
* #class Model
* #constructor
*/
window.Model = function(){}
....
And a file activerecord.js:
(function(){
/**
* #class ActiveRecord
* #constructor
window.ActiveRecord = function(){}
....
/**
* #method Model.hasMany
* #param {Class} model
*/
function hasMany(model) {}
})() ;
As you can see, the method 'hasMany' should show up under the class documentation of Model. However, it doesn't. Is something like this possible ?
Thanks a lot
See the #for tag: http://yui.github.io/yuidoc/syntax/index.html#for
/**
* Some method "hasMany" disconnected from its class "Model".
*
* #method hasMany
* #for Model
* #param {Class} model
*/
function hasMany(model) {}
Related
I'm using the documentation package, but cannot figure out how to get it to document class properties (that aren't defined via getters and setters).
As the following just generates class documentation for SomeClass, but omits the someProperty documentation.
/**
* SomeClass is an example class for my question.
* #class
* #constructor
* #public
*/
class SomeClass {
constructor () {
this.someProperty = true // how do I document this?
}
/**
* someProperty is an example property that is set to `true`
* #property {boolean} someProperty
* #public
*/
}
An aside: the #constructor on the class jsdoc is a documentation thing.
Move the JSDoc for someProperty into the constructor where it is first defined:
/**
* SomeClass is an example class for my question.
* #class
* #constructor
* #public
*/
class SomeClass {
constructor () {
/**
* someProperty is an example property that is set to `true`
* #type {boolean}
* #public
*/
this.someProperty = true
}
}
I'm unsure if there is a way of accomplishing it with the documentation package using an approach that doesn't involve inlining the JSDocs into the constructor.
Another way is to declare them in class documentation as follows:
/**
* Class definition
* #property {type} propName - propriety description
* ...
*/
class ClassName {
constructor () {...}
...
}
You can declare properties in a class, and use #type to declare a type for them. Worked in VSCode 1.70.2 with in a plain ECMAScript Module.
class Foo {
/**
* Some bary data
* #type { BarClass }
*/
bar;
}
let f = new Foo();
f.bar; // Intellisense can tell you type and purpose
I ask this mostly from a Angular perspective (but any advice would help). I have JSDoc's on my functions but it makes the code look very messy. I would just like to know if there is a way to move the JSDoc's to some type of external file.
An example of my JSDoc's:
/**
* Does a GET call on the service MyGetCall
* #param {string} pUserID - 1st Parameter: User Login ID
* #param {string} pPassword - 2nd Parameter: User Password
* #returns The Call's Http Observable (subscribe to this function).
* #example this.flowservice.MyGetCall('Johnny', 'MySuperSecretPassword')
* .subscribe(response => {
* console.log(response)
* });
*/
MyGetCall(pUserID: string, pPassword: string): Observable<any> {
const temp = this.httpclient.get<JSON>(`http://XXX/MyGetCall?userid=${pUserID}&password=${pPassword}`, {headers: this.headers});
return temp;
}
So in this example I would like to remove all the JSDoc's and put it in some kind of external file (jsdocs.xxx). This file would then look something like this:
MyGetCall:
/**
* Does a GET call on the service MyGetCall
* #param {string} pUserID - 1st Parameter: User Login ID
* #param {string} pPassword - 2nd Parameter: User Password
* #returns The Call's Http Observable (subscribe to this function).
* #example this.flowservice.MyGetCall('Johnny', 'MySuperSecretPassword')
* .subscribe(response => {
* console.log(response)
* });
*/
MyOtherFunction:
...
MyOtherOtherFunction:
...
Then I can import this file (jsdocs.xxx) somewhere for it to work with my app. For anyone that has used JSDoc's I hope this makes sense.
If, inline, I would document a class method like so:
/**
* #class
* #alias fileReader
*/
function fileReader() {
/**
* Tells the caller if it can handle the given file by returning a boolean.
*
* #param {File} file A `File` object.
* #returns {boolean} `true` if this reader can read a file.
*/
this.canRead = function (file) {
...
};
}
Instead, I could document my method somewhere else:
/**
* #class
* #alias fileReader
*/
function fileReader() {
this.canRead = function (file) {
...
};
}
And the documentation could be in a different file, like so:
/**
* Tells the caller if it can handle the given file by returning a boolean.
*
* #function canRead
* #memberof fileReader
* #instance
* #param {File} file A `File` object.
* #returns {boolean} `true` if this reader can read a file.
*/
The #function parameter defines the name of the function if the jsdoc isn't immediately followed by an actual function. The #memberof tells it the parent class or namespace. The #instance says that it is a method that requires an instantiated class rather.
For your example, I'm guessing that the documentation would be
/**
* Does a GET call on the service MyGetCall
* #function MyGetCall
* #memberof flowservice
* #instance
* #param {string} pUserID - 1st Parameter: User Login ID
* #param {string} pPassword - 2nd Parameter: User Password
* #returns The Call's Http Observable (subscribe to this function).
* #example this.flowservice.MyGetCall('Johnny', 'MySuperSecretPassword')
* .subscribe(response => {
* console.log(response)
* });
*/
This answer is mostly catered to VS Code if you're hoping to get Intellisense to pick up your types.
I've had success with simply creating my types in a typedefs.js file and referencing the type by using the ts/vscode import(path/to/file).Foo tag.
JSDoc does not support this syntax out of the box, so I suggest also using jsdoc-tsimport-plugin in order to parse your docs.
Eg: typedef.js:
/**
* #typedef {Object} Foo
* #property {string} id
*/
/**
* #typedef {Object} Bar
* #property {string[]} things
*/
// having to export an empty object here is annoying,
// but required for vscode to pass on your types.
export {};
coolFunction.js
/**
* This function is super dope
* #param {import('../typedef').Foo} foo - a foo
* #return {import('../typedef').Bar} bar - an array of bars
*/
export function (foo) {
// do cool things
return bar;
}
I'm currently writing an app in Object Oriented JavaScript, and I have a method which adds various functions on runtime to a function's prototype chain. The problem with this, is that when I try to use them in WebStorm i get an JSUnresolvedFunction error.
I've tried adding JSDoc to my code in the constructor and in the code itself but it still wont recognize the methods. Here is my code:
/**
* Example class
* #constructor
*
* #member {Function} OnConnect <-- Doesn't work
* #var {Function} OnConnect <-- Doesn't work either
* #typedef {Function} OnConnect <-- You get the deal
* #property {Function} OnConnect <-- Same for this
*/
function MyClass()
{
// Add methods dynamically
this.addMethods(["OnConnect", "OnDisconnect"]);
// Add callback listener to 'OnConnect'
// This is where WebStorm doesn't recognize my methods
this.OnConnect(function() {
console.log('Callback fired!');
});
}
/**
* Add methods which do the same thing to the class
* #param {Array} methods
* #returns {void}
*/
MyClass.prototype.addMethods = function(methods)
{
for (var i in methods) {
this[methods[i]] = function(callback) {
/** Tons of re-used logic here */
}
}
}
just remove everything except the #property
/**
* Example class
* #constructor
*
* #property {Function} OnConnect
*/
function MyClass()
{
// Add methods dynamically
this.addMethods(["OnConnect", "OnDisconnect"]);
// Add callback listener to 'OnConnect'
// This is where WebStorm doesn't recognize my methods
this.OnConnect(function() {
console.log('Callback fired!');
});
}
/**
* Add methods which do the same thing to the class
* #param {Array} methods
* #returns {void}
*/
MyClass.prototype.addMethods = function(methods)
{
for (var i in methods) {
this[methods[i]] = function(callback) {
/** Tons of re-used logic here */
}
}
}
How do I document a member function from a father class. There is a class A with a member function Afunc(), and I am gonna document class B extends A.
I do not overwrite Afunc() in B, yet I need the function Afunc() appear in my document, how do I do it?
I wrote
/**
* description
* #function Afunc
* #memberOf A
*/
It works that appears Afunc in the document, yet there is a <static> tag at the start of the function name.
How do I solve it?
Thanks everyone.
jsdoc 3.2.2 does what you want by default. In this example, the method B.foo will automatically be documented because B extends A and does not override foo:
/**
* #class
*/
function A() {
}
/**
* Foo the flerbl.
* #param {Object} flerbl The flerbl.
*/
A.prototype.foo = function (flerbl) {
};
/**
* #class
* #extends A
*/
function B() {
}
B.prototype = new A();
Otherwise, you must use # in your #memberof tag to mark the object as an belonging to an instance of the class:
/**
* description
* #function Afunc
* #memberof A#
*/
I am trying to automate a particular module in our JS library and am stuck at a point where I want to define a set of properties (lets say an object that goes as construction parameter of a class).
/**
* This function initiates world peace!
* #constructor
* #param {object} defaults - The options to initiate peace.
* #param {number} defaults.issues - The number of issues being taken up.
* #param {string} defaults.source - The name of the location where process starts.
*/
var WorldPeace = function (defaults) {
// code here
};
It is well and good had all properties of the construction was defined at one location. Unfortunately, my code has a number of modules contributing to that construction properties. Lets say, at some other portion of the code (in a later file) causes to have a couple of more properties
* #param {Date} defaults.start - The date when the process started.
* #param {Date} defaults.stop - The date when the process should stop.
How do I go about adding to the original set of properties that I had previously defined for WorldPeace function? Doing something like a mixin or subclassing the properties would be going overboard! As such, if I can simply inject to a property list definition it would be great.
The easiest method is to use a record type:
/**
* This function initiates world peace!
* #constructor
* #param {{issues: number, source: string}} defaults - options to initiate peace.
*/
var WorldPeace = function (defaults) {
// code here
};
You could also implement an interface:
/** #interface */
var WordPeaceDefaults;
/** #type {number} */
WorldPeaceDefaults.prototype.issues;
/** #type {string} */
WorldPeaceDefaults.prototype.source;
/**
* This function initiates world peace!
* #constructor
* #param {WorldPeaceDefaults} defaults - options to initiate peace.
*/
var WorldPeace = function (defaults) {
// code here
};
/**
* #constructor
* #implements {WorldPeaceDefaults}
*/
function MyWorldPeaceDefaults() {}
/** #type {number} */
MyWorldPeaceDefaults.prototype.issues = 0;
/** #type {string} */
MyWorldPeaceDefaults.prototype.source = '';
WordPeace(new MyWorldPeaceDefaults);
Another way to do it would be to use a typedef:
/**
* #typedef {{
* issues: number,
* source: string
* }}
*/
var WorldPeaceOptions;
/**
* #constructor
* #param {WorldPeaceOptions} defaults
*/
var WorldPeace = function (defaults) {
// code here
};