Usage of ngdocs with controller properties in angularJS - angularjs

I am just starting to get to grip using grunt-ngdocs for my angular application and so far so good.
But I would now like to document some properties of another documented prperty in one of my controllers.
Consider the following code:
(function() {
'use strict';
/**
* #ngdoc controller
* #name app.mymodule.controller:MyController
* #description
* A Controller
*/
angular
.module('app.mymodule')
.controller('MyController', Controller);
Controller.$inject = ['someService', 'otherService', '$state'];
function Controller(someService, otherService, $state) {
/**
* #ngdoc property
* #name vm
* #propertyOf app.mymodule.controller:MyController
* #description
* A named variable for the `this` keyword representing the ViewModel
*/
var vm = this,
searchText;
vm.customerService = customerService;
vm.fetchCollection = fetchCollection;
vm.deleteCustomer = deleteCustomer;
initialise();
function initialise() {
//logic
}
/**
* #ngdoc
* #name fetchCollection
* #methodOf app.mymodule.controller:MyController
*
* #description
* Function to retrieve records from the backend service
* #example
* vm.fetchCollection(page, perPage);
* #param {int} page The number of the page of data to be retrieved
* #param {int} perPage The number of items per page to be retrieved
* #returns {object} The response object returned from a httpPromise
*/
function fetchCollection(page, perPage){
//logic
}
function deleteCustomer(model) {
//logic
}
})();
As you can see, I have some properties hanging off the vm variable which are typically references to functions defined in the controller.
Using the ngdocs\jsdocs documentation syntax above I can get the vm property to output in my documentation folder, but I am unsure how to document the properties of the vm object itself.
Is there a sensible or recommended way to do this? I did wonder about not documenting vm altogether and just document each of the vm.xxx separately, but I'm not so sure about this!
Thanks

It is not very clear in the documentation, but you have to use the hash in the name.
Try this.
/**
* #ngdoc property
* #name app.mymodule.controller:MyController#vm
* #propertyOf app.mymodule.controller:MyController
* #description
* A named variable for the `this` keyword representing the ViewModel
*/

Related

Laravel Orchid: How can the post entry in the database be retrieved from in the PostEditScreen.php?

Laravel Orchid: How can the post entry in the database be retrieved from in the PostEditScreen.php?
In a function in the PostEditScreen.php, how can the entry in the database that is being referred to by the PostEditScreen be accessed?
Post::find($post.id) is not working.
Any help would be greatly appreciated.
/**
* Query data.
*
* #param Post $post
*
* #return array
*/
public function query(Post $post): array
{
// This will already be a record of your model.
}
Or you can do it explicitly
/**
* Query data.
*
* #param int $id
*
* #return array
*/
public function query(int $id): array
{
Post::find($id)
}
This is stated in the laravel documentation: https://laravel.com/docs/7.x/routing#route-model-binding

How do I paginate a collection or custom query into API json in Laravel?

I have a complex query that is not based on any specific model table that I want to paginate output for. However laravel's built in pagination relies on models and tables. How can I paginate a collection and have the output match up with laravel's built in pagination output format?
I keep this in an app\Core\Helpers class so that I can call them from anywhere as \App\Core\Helpers::makePaginatorForCollection($query_results). The most likely place to use this is the last line of a controller that deals with complex queries.
In app/Http/Controllers/simpleExampleController.php
/**
* simpleExampleController
**/
public function myWeirdData(Request $request){
$my_unsafe_sql = '...';//never do this!!
$result = DB::statement(DB::raw($my_unsafe_sql));
return \App\Core\Helpers::makePaginatorForCollection($result);
}
In app\Core\Helpers.php or anywhere you like that auto loads.
/**
* This will match laravel's built in Model::paginate()
* because it uses the same underlying code.
*
* #param \Illuminate\Support\Collection $collection
*
* #return \Illuminate\Pagination\LengthAwarePaginator
*/
public static function makePaginatorForCollection(\Illuminate\Support\Collection $collection){
$current_page = (request()->has('page')? request()->page : 1) -1;//off by 1 (make zero start)
$per_page = (request()->has('per_page')? request()->per_page : config('api.pagination.per_page')) *1;//make numeric
$page_data = $collection->slice($current_page * $per_page, $per_page)->all();
return new \Illuminate\Pagination\LengthAwarePaginator(array_values($page_data), count($collection), $per_page);
}
/**
* Copy and refactor makePaginatorForCollection()
* if collection building is too slow.
*
* #param $array
*
* #return \Illuminate\Pagination\LengthAwarePaginator
*/
public static function makePaginatorForArray($array){
$collection = collect($array);
return self::makePaginatorForCollection($collection);
}

AngularJS 1.5 ngOptions Comparison for Displaying a Plain Array

Can anyone tell me why the model option in the first example is selected, and the second one does not for a plain array:
// Plain old array
vm.owner = ['example', 'example2', 'example3', ...];
Where the model vm.model.address.owner = 2;
// EXAMPLE 1 - Works
// Force index to be a number: using id*1 instead of it being a string:
// and the option ('example3') is selected based on the model value of 2
// indicating the index
<select id="owner"
name="owner"
placeholder="Residential Status"
ng-model="vm.model.address.owner"
ng-required="true"
ng-options="id*1 as owner for (id, owner) in vm.owner">
<option value="">Select Value</option>
</select>
Attempting to not use a hack and using track by instead index 2 is not selected even though the value is still set in the model.
// EXAMPLE 2 - Doesn't Work
// Markup doesn't show value to be a string: using track by, but the
// option set in the model doesn't cause the option to be selected it
// remains as the default with a value of ''
<select id="owner"
name="owner"
placeholder="Residential Status"
ng-model="vm.model.address.owner"
ng-required="true"
ng-options="owner for (id, owner) in vm.owner track by id">
<option value="">Select Value</option>
</select>
I find ngOptions to be super confusing so any explanation or solution for example 2 since it is cleaner and not a hack would be great.
Didn't find a solution using track by, but the AngularJS docs for Select had a solution using a parser and formatter so I could get away from using the hack in the question. I tweaked it a bit so if the key was a string it will leave it alone, otherwise it converts it, and this seems to work. Any criticisms or issues that I don't see please comment, otherwise hope this helps someone.
(function () {
'use strict';
/**
* Binds a select field to a non-string value via ngModel parsing and formatting,
* which simply uses these pipelines to convert the string value.
* #constructor
* #ngInject
* ---
* NOTE: In general matches between a model and an option is evaluated by strict
* comparison of the model value against the value of the available options.
* Setting the option value with the option's "value" attribute the value
* will always be a "string", which means that the model value must also
* be a string, otherwise the select directive cannot match them
* reliably.
*/
function selectConvertKey(_) {
return {
require: 'ngModel',
link: function ($scope, $element, $attrs, $ctrl) {
var ngModelCtrl = $ctrl;
// Do nothing if no ng-model
if (!ngModelCtrl) {
return;
}
// ---
// PRIVATE METHODS.
// ---
/**
* Convert the key to a number if the key is a number.
* #param key
* #returns {Number}
* ---
* NOTE: Using Number() instead of parseInt() means that a string
* composed of letters and numbers, and start with a number will
* not be converted.
*/
function selectConvertKeyParser(key) {
var keyAsNumber = Number(key);
// Check if the key is not a number
if(_.isNaN(keyAsNumber)) {
return key;
}
return keyAsNumber;
}
/**
* Convert the key to a string.
* #param key
* #returns {string}
*/
function selectConvertKeyFormatter(key) {
return '' + key;
}
// ---
// MODEL PROPERTIES.
// ---
/**
* Formatters used to control how the model changes are formatted
* in the view, also known as model-to-view conversion.
* ---
* NOTE: Formatters are not invoked when the model is changed
* in the view. They are only triggered if the model changes
* in code. So you could type forever into the input, and
* the formatter would never be invoked.
*/
ngModelCtrl.$formatters.push(selectConvertKeyFormatter);
/**
* Parsers used to control how the view changes read from the
* DOM are sanitized/formatted prior to saving them to the
* model, and updating the view if required.
*/
ngModelCtrl.$parsers.push(selectConvertKeyParser);
}
};
}
selectConvertKey.$inject = [
'_'
];
angular
.module('app')
.directive('selectConvertKey', selectConvertKey);
})();
Yes, the problem appears to be that the select is being bound to a non-string value. If you do the following, it would work:
//controller
vm.model.address.owner = "2"
//html
ng-options="id as owner for (id, owner) in vm.owner"
See Angularjs ng-options using number for model does not select initial value.
Also, if you want to leave the model value as a number (2, not "2") you can try this:
ng-options="vm.owner.indexOf(owner) as owner for (id, owner) in vm.owner"
However, that may not be any less "hackish" than your working first example:
ng-options="id*1 as owner for (id, owner) in vm.owner">
See the first answer at AngularJS ng-option get index.

Document a constant using ngDoc

How would one go about documenting a constant using ngDoc? I don't see any angular specific documentation for documenting values registered with .constant, and the jsDoc syntax for constants doesn't seem to generate any actual docs when it's run through ngDoc.
Ex:
/**
* #constant
* #name WHITE
*
* #description
* The color white!
**/
module.constant( 'WHITE', '#fff' );
ngDocs currently doesn't provide a way to document constants. As you can see in its templating source code. There isnt relevant html_usage_* method.
I document constants like this, it shows a APP_CONFIG as a module then.
/**
* #ngdoc object
* #name APP_CONFIG
* #description
* constant...
* #example
* APP_CONFIG is injectable as constant (as a service even to .config())
* <pre>
* (...) .config(function ($APP_CONFIG) {
* </pre>
*/
It should be #const
/** #const */ var MY_BEER = 'stout';
/**
* My namespace's favorite kind of beer.
* #const {string}
*/
mynamespace.MY_BEER = 'stout';
/** #const */ MyClass.MY_BEER = 'stout';
/**
* Initializes the request.
* #const
*/
mynamespace.Request.prototype.initialize = function() {
// This method cannot be overridden in a subclass.
};
See the constant part http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Constants and the comments part http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Comments#Comments for more informations

How to Implement URL parameter service correctly

I'm about to design an service which handles URL parameters in AngularJS. Currently I have two different kinds of parameters.
Single valued
&param=myValue
Multi valued
&param=lorem,ipsum,dolor
I'm not sure whether to implement a setter for both single and multi valued parameters.
/**
* Set parameter
*
* #param {string} name
* #param {string|array} values
* #param {boolean} multi
*/
setParam: function(name, value, multi) { }
Or if each type of parameter should get its own setter?
/**
* Set single valued parameter
*
* #param {string} name
* #param {string} value
*/
setSingleValuedParam: function(name, value) { }
/**
* Set multi valued parameter
*
* #param {string} name
* #param {array} values
*/
setMultiValuedParam: function(name, array) { }
Please note: This is pseudo-code and does not work!
Even the single one that you show is technically an array with a single element. So I would just implement the multi-valued one.
/**
* Set parameters
*
* #param {string} name
* #param {array} values
*/
setMultiValuedParam: function(name, array) { }
When the query comes, split it by , and there will be 0 or more parameters in the array.
FYI: Definitely include a possibility of 0 parameters, because even if your program does not call with 0, since this is a query parameter, someone else could just hit the URL directly.

Resources