ExtJS Geolocation usage for classic toolkit - javascript
I'm following this Geolocation usage for Sencha Touch tutorial but I need to use for both classic and modern toolkit. During sencha app watch / refresh / build commands I get the error for the requirement for Ext.util.Geolocation class;
C2008: Requirement had no matching files (Ext.util.Geolocation)
[ERR] BUILD FAILED
[ERR] com.sencha.exceptions.ExBuild: Failed to find any files for /..../WeatherView.js::ClassRequire::Ext.util.Geolocation
[ERR] at sun.reflect.Delegat
[ERR] ingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Despite when I try to sencha app watch modern command, then I get an error for Ext.form.field.Text. I can not disable textfield usage in my app. So what could be the solution for Geolocation service?
Here is a code snippet which occurs the error:
refreshGeoLocation : function( refresh ) {
if (!this.geoLocationObj || (true == refresh)) {
Ext.create('Ext.util.Geolocation', {
autoUpdate: false,
listeners: {
locationupdate: function (geo) {
Ext.Msg.alert('Refresh Geolocation', 'New latitude: ' + geo.getLatitude() + ' , Longitude: ' + geo.getLongitude(), Ext.emptyFn);
},
locationerror: function (geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if (bTimeout) {
alert('Timeout occurred');
} else {
alert('Error occurred');
}
}
}
});
this.geoLocationObj.updateLocation();
}
}
(*) Tutorial: https://wtcindia.wordpress.com/2013/02/08/using-yahoo-weather-api-in-sencha-touch/
Reason of this error (Requirement had no matching files (Ext.util.Geolocation)) is may be somewhere(app.js or Application.js) you have requires
this class Ext.util.Geolocation.
Ext.util.Geolocation is only available in modern toolkit. So instead of app.js you should requires inside modern folder.
For this "Despite when I try to sencha app watch modern command, then I get an error for Ext.form.field.Text."
This class Ext.form.field.Text available only classic toolkit.
Instead of this Ext.form.field.Text you need to use this Ext.field.Text inside of modern toolkit.
If you want to use Geolocation in classic toolkit, so you need to add custom class inside classic folder.
For further details you can refer this my ExtJS-GeoLocation project.
I hope this will guide you to solve your error..
/**
* Provides a cross browser class for retrieving location information.
* Source from https://docs.sencha.com/extjs/6.0.0/modern/src/Geolocation.js.html
* Based on the [Geolocation API Specification](http://dev.w3.org/geo/api/spec-source.html)
*
* When instantiated, by default this class immediately begins tracking location information,
* firing a {#link #locationupdate} event when new location information is available. To disable this
* location tracking (which may be battery intensive on mobile devices), set {#link #autoUpdate} to `false`.
*
* When this is done, only calls to {#link #updateLocation} will trigger a location retrieval.
*
* A {#link #locationerror} event is raised when an error occurs retrieving the location, either due to a user
* denying the application access to it, or the browser not supporting it.
*
* The below code shows a GeoLocation making a single retrieval of location information.
*
* //{GeoLocation} is your application name
* var geo = Ext.create('GeoLocation.util.Geolocation', {
* autoUpdate: false,
* listeners: {
* locationupdate: function(geo) {
* Ext.Msg.alert('Success', `New latitude: ${geo.getLatitude()} <br>New Longitude: ${geo.getLongitude()}`);
* },
* locationerror: function(geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
* if(bTimeout){
* Ext.Msg.alert('Error', 'Timeout occurred.');
* } else {
* Ext.Msg.alert('Error', 'Error occurred');
* }
* }
* }
* });
* geo.updateLocation();
*/
//{GeoLocation} is your application name
Ext.define('GeoLocation.util.Geolocation', {
extend: 'Ext.Evented',
alternateClassName: ['Geolocation'],
config: {
/**
* #event locationerror
* Raised when a location retrieval operation failed.
*
* In the case of calling updateLocation, this event will be raised only once.
*
* If {#link #autoUpdate} is set to `true`, this event could be raised repeatedly.
* The first error is relative to the moment {#link #autoUpdate} was set to `true`
* (or this {#link Ext.util.Geolocation} was initialized with the {#link #autoUpdate} config option set to `true`).
* Subsequent errors are relative to the moment when the device determines that it's position has changed.
* #param {Ext.util.Geolocation} this
* #param {Boolean} timeout
* Boolean indicating a timeout occurred
* #param {Boolean} permissionDenied
* Boolean indicating the user denied the location request
* #param {Boolean} locationUnavailable
* Boolean indicating that the location of the device could not be determined.
* For instance, one or more of the location providers used in the location acquisition
* process reported an internal error that caused the process to fail entirely.
* #param {String} message An error message describing the details of the error encountered.
*
* This attribute is primarily intended for debugging and should not be used
* directly in an application user interface.
*/
/**
* #event locationupdate
* Raised when a location retrieval operation has been completed successfully.
* #param {Ext.util.Geolocation} this
* Retrieve the current location information from the GeoLocation object by using the read-only
* properties: {#link #latitude}, {#link #longitude}, {#link #accuracy}, {#link #altitude}, {#link #altitudeAccuracy}, {#link #heading}, and {#link #speed}.
*/
/**
* #cfg {Boolean} autoUpdate
* When set to `true`, continually monitor the location of the device (beginning immediately)
* and fire {#link #locationupdate} and {#link #locationerror} events.
*/
autoUpdate: true,
/**
* #cfg {Number} frequency
* The frequency of each update if {#link #autoUpdate} is set to `true`.
*/
frequency: 10000,
/**
* #cfg {Number} latitude
* Read-only property representing the last retrieved
* geographical coordinate specified in degrees.
* #readonly
*/
latitude: null,
/**
* #cfg {Number} longitude
* Read-only property representing the last retrieved
* geographical coordinate specified in degrees.
* #readonly
*/
longitude: null,
/**
* #cfg {Number} accuracy
* Read-only property representing the last retrieved
* accuracy level of the latitude and longitude coordinates,
* specified in meters.
*
* This will always be a non-negative number.
*
* This corresponds to a 95% confidence level.
* #readonly
*/
accuracy: null,
/**
* #cfg {Number} altitude
* Read-only property representing the last retrieved
* height of the position, specified in meters above the ellipsoid
* [WGS84](http://dev.w3.org/geo/api/spec-source.html#ref-wgs).
* #readonly
*/
altitude: null,
/**
* #cfg {Number} altitudeAccuracy
* Read-only property representing the last retrieved
* accuracy level of the altitude coordinate, specified in meters.
*
* If altitude is not null then this will be a non-negative number.
* Otherwise this returns `null`.
*
* This corresponds to a 95% confidence level.
* #readonly
*/
altitudeAccuracy: null,
/**
* #cfg {Number} heading
* Read-only property representing the last retrieved
* direction of travel of the hosting device,
* specified in non-negative degrees between 0 and 359,
* counting clockwise relative to the true north.
*
* If speed is 0 (device is stationary), then this returns `NaN`.
* #readonly
*/
heading: null,
/**
* #cfg {Number} speed
* Read-only property representing the last retrieved
* current ground speed of the device, specified in meters per second.
*
* If this feature is unsupported by the device, this returns `null`.
*
* If the device is stationary, this returns 0,
* otherwise it returns a non-negative number.
* #readonly
*/
speed: null,
/**
* #cfg {Date} timestamp
* Read-only property representing when the last retrieved
* positioning information was acquired by the device.
* #readonly
*/
timestamp: null,
//PositionOptions interface
/**
* #cfg {Boolean} allowHighAccuracy
* When set to `true`, provide a hint that the application would like to receive
* the best possible results. This may result in slower response times or increased power consumption.
* The user might also deny this capability, or the device might not be able to provide more accurate
* results than if this option was set to `false`.
*/
allowHighAccuracy: false,
/**
* #cfg {Number} timeout
* The maximum number of milliseconds allowed to elapse between a location update operation
* and the corresponding {#link #locationupdate} event being raised. If a location was not successfully
* acquired before the given timeout elapses (and no other internal errors have occurred in this interval),
* then a {#link #locationerror} event will be raised indicating a timeout as the cause.
*
* Note that the time that is spent obtaining the user permission is **not** included in the period
* covered by the timeout. The `timeout` attribute only applies to the location acquisition operation.
*
* In the case of calling `updateLocation`, the {#link #locationerror} event will be raised only once.
*
* If {#link #autoUpdate} is set to `true`, the {#link #locationerror} event could be raised repeatedly.
* The first timeout is relative to the moment {#link #autoUpdate} was set to `true`
* (or this {#link Ext.util.Geolocation} was initialized with the {#link #autoUpdate} config option set to `true`).
* Subsequent timeouts are relative to the moment when the device determines that it's position has changed.
*/
timeout: Infinity,
/**
* #cfg {Number} maximumAge
* This option indicates that the application is willing to accept cached location information whose age
* is no greater than the specified time in milliseconds. If `maximumAge` is set to 0, an attempt to retrieve
* new location information is made immediately.
*
* Setting the `maximumAge` to Infinity returns a cached position regardless of its age.
*
* If the device does not have cached location information available whose age is no
* greater than the specified `maximumAge`, then it must acquire new location information.
*
* For example, if location information no older than 10 minutes is required, set this property to 600000.
*/
maximumAge: 0,
/**
* #private
*/
provider: undefined
},
updateMaximumAge: function() {
if (this.watchOperation) {
this.updateWatchOperation();
}
},
updateTimeout: function() {
if (this.watchOperation) {
this.updateWatchOperation();
}
},
updateAllowHighAccuracy: function() {
if (this.watchOperation) {
this.updateWatchOperation();
}
},
applyProvider: function(config) {
if (Ext.feature.has.Geolocation) {
if (!config) {
if (navigator && navigator.geolocation) {
config = navigator.geolocation;
} else if (window.google) {
config = google.gears.factory.create('beta.geolocation');
}
}
} else {
this.fireEvent('locationerror', this, false, false, true, 'This device does not support Geolocation.');
}
return config;
},
updateAutoUpdate: function(newAutoUpdate, oldAutoUpdate) {
var me = this,
provider = me.getProvider();
if (oldAutoUpdate && provider) {
Ext.uninterval(me.watchOperationId);
me.watchOperationId = null;
}
if (newAutoUpdate) {
if (!provider) {
me.fireEvent('locationerror', me, false, false, true, null);
return;
}
try {
me.updateWatchOperation();
} catch (e) {
me.fireEvent('locationerror', me, false, false, true, e.message);
}
}
},
/**
* #private
*/
updateWatchOperation: function() {
var me = this,
provider = me.getProvider();
// The native watchPosition method is currently broken in iOS5...
if (me.watchOperationId) {
Ext.uninterval(me.watchOperationId);
}
function pollPosition() {
provider.getCurrentPosition(
Ext.bind(me.fireUpdate, me),
Ext.bind(me.fireError, me),
me.parseOptions()
);
}
pollPosition();
me.watchOperationId = Ext.interval(pollPosition, this.getFrequency());
},
/**
* Executes a onetime location update operation,
* raising either a {#link #locationupdate} or {#link #locationerror} event.
*
* Does not interfere with or restart ongoing location monitoring.
* #param {Function} callback
* A callback method to be called when the location retrieval has been completed.
*
* Will be called on both success and failure.
*
* The method will be passed one parameter, {#link Ext.util.Geolocation}
* (**this** reference), set to `null` on failure.
*
* geo.updateLocation(function (geo) {
* alert('Latitude: ' + (geo !== null ? geo.latitude : 'failed'));
* });
*
* #param {Object} [scope]
* The scope (**this** reference) in which the handler function is executed.
*
* **If omitted, defaults to the object which fired the event.**
*
* #param {Object} [positionOptions] (private) See W3C spec
*/
updateLocation: function(callback, scope, positionOptions) {
var me = this,
provider = me.getProvider();
var failFunction = function(message, error) {
if (error) {
me.fireError(error);
} else {
me.fireEvent('locationerror', me, false, false, true, message);
}
if (callback) {
callback.call(scope || me, null, me); //last parameter for legacy purposes
}
};
if (!provider) {
failFunction(null);
return;
}
try {
provider.getCurrentPosition(
//success callback
function(position) {
me.fireUpdate(position);
if (callback) {
callback.call(scope || me, me, me); //last parameter for legacy purposes
}
},
//error callback
function(error) {
failFunction(null, error);
},
positionOptions || me.parseOptions()
);
} catch (e) {
failFunction(e.message);
}
},
/**
* #private
*/
fireUpdate: function(position) {
var me = this,
coords = position.coords;
this.position = position;
me.setConfig({
timestamp: position.timestamp,
latitude: coords.latitude,
longitude: coords.longitude,
accuracy: coords.accuracy,
altitude: coords.altitude,
altitudeAccuracy: coords.altitudeAccuracy,
heading: coords.heading,
speed: coords.speed
});
me.fireEvent('locationupdate', me);
},
/**
* #private
*/
fireError: function(error) {
var errorCode = error.code;
this.fireEvent('locationerror', this,
errorCode == error.TIMEOUT,
errorCode == error.PERMISSION_DENIED,
errorCode == error.POSITION_UNAVAILABLE,
error.message == undefined ? null : error.message
);
},
/**
* #private
*/
parseOptions: function() {
var timeout = this.getTimeout(),
ret = {
maximumAge: this.getMaximumAge(),
enableHighAccuracy: this.getAllowHighAccuracy()
};
//Google doesn't like Infinity
if (timeout !== Infinity) {
ret.timeout = timeout;
}
return ret;
},
destroy: function() {
this.setAutoUpdate(false);
this.callParent();
}
});
Related
async in JavaScript - When to use await (and when to not) - 'await' has no effect on the type of this expression .ts(80007)
I am seeing this issue a lot in my code and I've seen similar posts about it on here but they don't seem linked to my issue specifically, which makes me think I'm missing something somewhere. The comment 'await' has no effect on the type of this expression.ts(80007) comes up (as an example case) in the async method below... /** * Deletes the account for the currently logged in user. */ async deleteAccount() { Logger.log('Deleting the currently logged in user', 'Auth') const service = ServiceFactory.profile() const operationState = await service.deleteUser() if (!operationState.succeeded) operationState.throw() }, Dropping through the stack, this calls through as follows to this method in the ProfileService class which is returned above in ServiceFactory.profile()... /** * Deletes a user. * #returns {ServiceOperation} The operation result. * #memberof ProfileService */ async deleteUser() { const operationState = new ServiceOperation('Delete User', true) const url = `${ this.baseUrl }?SchemeId=${ this.schemeId }` Logger.log(url, 'Request [DELETE]') try { return this.processResponse(await Axios.delete(url), operationState, 'deleteUser') } catch (err) { return this.failOperation(err, operationState, 'deleteUser') } } The issue seems related to the processResponse method on the base class that transforms my JSON responses from my back end into ServiceOperation classes which tracks running state, success, merges multiple results and transforms different types of error responses to be consistent for the app to handle - the code for which is largely irrelevant to add here... /** * Handles a succesfull data changing operation and processes the response safely. * * #param {Object} response The service response. * #param {ServiceOperation} operationState * #param {string} [methodName='?'] The name of the calling method. * #returns {ServiceOperation} The modified operation state. * * #memberof Service */ processResponse(response, operationState, methodName = '?') { if (response.data !== false && !response.data || response.data == null) { operationState.complete(true) } else { operationState.complete(true, response.data) } Logger.logObject(response, `Operation completed [${ methodName }]`, this.loggingCategory) return operationState } failOperation is simply processResponse fail call method... /** * Handles a failed operation. * * #param {Error} error * #param {ServiceOperation} operationState * #param {string} [methodName='?'] The name of the calling method. * #returns {ServiceOperation} The modified operation state. * * #memberof Service */ failOperation(error, operationState, methodName = '?') { operationState.fail(error) Logger.logObject(operationState, `Data service failed [${ methodName }]`, this.loggingCategory) return operationState } Both of the above methods are part of the Service class which is extended to form the ProfileService class earlier on that contains the deleteUser function (The Service class acts as a base class for each of the service classes in the app. Where I'm a bit confused here is that processResponse isn't async (and doesn't need to be). The awaited call is awaited in the method that calls it. Is this just a case of the editor not picking it up or, as I suspect, is it that I'm losing the underlying promise when I process the data - If that's the case how can I get the promise to surface up for the method result that processResponse needs? processResponse is a generic method that handles all the service method results I have in my app so merging the methods isn't viable. I've considered making processResponse itself async and using await on it but that seems logically like it would do absolutely nothing as there is nothing to really await. Functionally the app code seems to be working fine so I'm loathe to start pulling it apart at this level until I understand exactly why it's moaning. EXTRA (but probably irrelevant) INFO This is the definition of the ServiceOperation class that the Service class and it's derivatives make use of. This is for completion only and is largely irrelevant. /** * Defines an operation performed through a service. * * #export * #class ServiceOperation */ export default class ServiceOperation { /** *Creates an instance of ServiceOperation. * #param {string} name * #param {boolean} [started=false] * #memberof ServiceOperation */ constructor(name, started = false) { this.name = name this.running = started this.completed = false this.succeeded = false } /** * Completes a service operation. * * #param {boolean} succeeded * #param {object} data Any data or error info returned * #returns {ServiceOperation} itself. * #memberof ServiceOperation */ complete(succeeded, data) { this.running = false this.completed = true this.succeeded = succeeded if (data !== undefined && data !== null || this.data !== undefined && this.data !== null) this.data = data return this } /** * Fails a service operation. * * #param {string} error An error * #returns {ServiceOperation} itself. * #memberof ServiceOperation */ fail(error) { this.complete(false) if (error && error.response && error.response.data) { this.data = error.response.data this.errorObject = error this.error = error.response.data.message ? error.response.data.message : error.message this.errorObject.message = this.error } else { this.error = error && error.message ? error.message : error this.errorObject = error } return this } /** * Throws the wrapped error object back for interrogation. * * #memberof ServiceOperation */ throw() { if (this.errorObject) throw this.errorObject else if (this.error) throw new Error(this.error) else throw new Error('Service Operation error') } /** * Merges another operation into this one, updating it's info. * * #param {ServiceOperation} operation * #param {boolean} includeData If not set then the data item will be eradicated if it is present. * #memberof ServiceOperation */ updateMergeFrom(operation, includeData = false) { this.running = operation.running this.completed = operation.completed this.succeeded = operation.succeeded if (!includeData && this.data) delete this.data else if (includeData && operation.data) this.data = operation.data if (operation.stillPending !== undefined) this.stillPending = operation.stillPending if (!this.error && operation.error) this.error = operation.error } /** * Generates an immediately completed operation. * * #static * #type {ServiceOperation} * #memberof ServiceOperation */ static get immediate() { return new ServiceOperation('Immediate').complete(true) } }
I found the answer to this digging through this article... https://github.com/microsoft/TypeScript/issues/34508 This seems to be a warning generated by the TypeScript compiler (although my project isn't even using TypeScript so - {shrug}) In order to make it go away you need to edit your JSDoc entry as follows... /** * Deletes a user. * #returns {ServiceOperation} The operation result. * #memberof ProfileService */ async deleteUser() { } becomes /** * Deletes a user. * #returns {Promise<ServiceOperation>} The operation result. * #memberof ProfileService */ async deleteUser() { } Thanks to #Bergi for getting my brain to look in the right place.
Error on a MasterDetail page
So I'm trying to recreate this app on SAP Web IDE: But I'm continuously getting this error: This is my App.Controller.js code: sap.ui.define([ "pt/procensus/ui5rv/controller/BaseController", "sap/ui/model/json/JSONModel" ], function (BaseController, JSONModel) { "use strict"; return BaseController.extend("pt.procensus.ui5rv.controller.App", { onInit : function () { var oViewModel, fnSetAppNotBusy, oListSelector = this.getOwnerComponent().oListSelector, iOriginalBusyDelay = this.getView().getBusyIndicatorDelay(); oViewModel = new JSONModel({ busy : true, delay : 0 }); this.setModel(oViewModel, "appView"); fnSetAppNotBusy = function() { oViewModel.setProperty("/busy", false); oViewModel.setProperty("/delay", iOriginalBusyDelay); }; this.getOwnerComponent().oWhenMetadataIsLoaded. then(fnSetAppNotBusy, fnSetAppNotBusy); // Makes sure that master view is hidden in split app // after a new list entry has been selected. oListSelector.attachListSelectionChange(function () { this.byId("idAppControl").hideMaster(); }, this); // apply content density mode to root view this.getView().addStyleClass(this.getOwnerComponent().getContentDensityClass()); } }); } ); This is my Base.Controller.js code: /*global history */ sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/core/routing/History" ], function(Controller, History) { "use strict"; return Controller.extend("pt.procensus.ui5rv.controller.BaseController", { /** * Convenience method for accessing the router in every controller of the application. * #public * #returns {sap.ui.core.routing.Router} the router for this component */ getRouter: function() { return this.getOwnerComponent().getRouter(); }, /** * Convenience method for getting the view model by name in every controller of the application. * #public * #param {string} sName the model name * #returns {sap.ui.model.Model} the model instance */ getModel: function(sName) { return this.getView().getModel(sName); }, /** * Convenience method for setting the view model in every controller of the application. * #public * #param {sap.ui.model.Model} oModel the model instance * #param {string} sName the model name * #returns {sap.ui.mvc.View} the view instance */ setModel: function(oModel, sName) { return this.getView().setModel(oModel, sName); }, /** * Convenience method for getting the resource bundle. * #public * #returns {sap.ui.model.resource.ResourceModel} the resourceModel of the component */ getResourceBundle: function() { return this.getOwnerComponent().getModel("i18n").getResourceBundle(); }, /** * Event handler for navigating back. * It checks if there is a history entry. If yes, history.go(-1) will happen. * If not, it will replace the current entry of the browser history with the master route. * #public */ onNavBack: function() { var sPreviousHash = History.getInstance().getPreviousHash(); if (sPreviousHash !== undefined) { // The history contains a previous entry history.go(-1); } else { // Otherwise we go backwards with a forward history var bReplace = true; this.getRouter().navTo("master", {}, bReplace); } } }); }); My App Folders: And I can't understand why is this happening. I've already removed the 'then' part and it gives me more errors... :/ Any help will be very much appreciated :)
Can you try this? At least this is how it works in my App.controller: this.getOwnerComponent().getModel().metadataLoaded() .then(fnSetAppNotBusy, fnSetAppNotBusy);
VueJS - Script not loaded when direct access to subpage
I'm currently working on a website with vue.js, and I use vue-route. There's a subroute (/blog/post-slug) that load a script (Prism: http://prismjs.com/) and fires it in the ready() state : import Prism from 'prismjs' module.exports = { Route: { waitForData: true }, data () { return { post: { } } }, ready () { Prism.highlightAll() } } When I reach the page from a link inside the site, it’s all good, loaded and working, the result is ok in the page. But if I reload the page or access it with a direct link from an external link, it’s not good. Here’s my route config, if it helps: /** * Router config */ module.exports = { /** * Config * #type {Object} */ config: { hasbang: false, history: true, saveScrollPosition: true, linkActiveClass: 'site-menu__link--active', transitionOnLoad: true }, /** * Before route starts transitioning * #param {Object} options.from Route we are transitioning from * #param {Object} options.to Route we are transitioning to * #param {Function} options.next Progress to the next step of the transition * #param {Function} options.abort Cancel / Reject the transition * #param {Function} options.redirect Cancel and redirect to a different route * #return {void} */ before ({from, to, next, abort, redirect}) { next() }, /** * After route has transitioned * #param {Object} options.from Route we are transitioning from * #param {Object} options.to Route we are transitioning to * #return {void} */ after ({from, to}) { if (typeof to.title !== 'undefined') { document.title = to.title } } } I guess something in particular happen when the view is loaded from inside the app, and not directly, but can’t find what. What am I missing? Thanks in advance for any hint.
JSDoc: Return object structure
How can I tell JSDoc about the structure of an object that is returned. I have found the #return {{field1: type, field2: type, ...}} description syntax and tried it: /** * Returns a coordinate from a given mouse or touch event * #param {TouchEvent|MouseEvent|jQuery.Event} e * A valid mouse or touch event or a jQuery event wrapping such an * event. * #param {string} [type="page"] * A string representing the type of location that should be * returned. Can be either "page", "client" or "screen". * #return {{x: Number, y: Number}} * The location of the event */ var getEventLocation = function(e, type) { ... return {x: xLocation, y: yLocation}; } While this parses successfully, the resulting documentation simply states: Returns: The location of an event Type: Object I am developing an API and need people to know about the object that they will get returned. Is this possible in JSDoc? I am using JSDoc3.3.0-beta1.
Define your structure separately using a #typedef: /** * #typedef {Object} Point * #property {number} x - The X Coordinate * #property {number} y - The Y Coordinate */ And use it as the return type: /** * Returns a coordinate from a given mouse or touch event * #param {TouchEvent|MouseEvent|jQuery.Event} e * A valid mouse or touch event or a jQuery event wrapping such an * event. * #param {string} [type="page"] * A string representing the type of location that should be * returned. Can be either "page", "client" or "screen". * #return {Point} * The location of the event */ var getEventLocation = function(e, type) { ... return {x: xLocation, y: yLocation}; }
An alternative to the suggestions already posted, you can use this format: /** * Get the connection state. * * #returns {Object} connection The connection state. * #returns {boolean} connection.isConnected Whether the authenticated user is currently connected. * #returns {boolean} connection.isPending Whether the authenticated user's connection is currently pending. * #returns {Object} connection.error The error object if an error occurred. * #returns {string} connection.error.message The error message. * #returns {string} connection.error.stack The stack trace of the error. */ getConnection () { return { isConnected: true, isPending: false, error } } which will give the following documentation output: Get the connection state. getConnection(): Object Returns Object: connection The connection state. boolean: connection.isConnected Whether the authenticated user is currently connected. boolean: connection.isPending Whether the authenticated users connection is currently pending. Object: connection.error The error object if an error occurred. string: connection.error.message The error message. string: connection.error.stack The stack trace of the error.
A clean solution is to write a class and return that. /** * #class Point * #type {Object} * #property {number} x The X-coordinate. * #property {number} y The Y-coordinate. */ function Point(x, y) { return { x: x, y: y }; } /** * #returns {Point} The location of the event. */ var getEventLocation = function(e, type) { ... return new Point(x, y); };
JS function prototype out of context node express
I have an issue using prototype in node with context. /** * Constructor. * * #param object opts The options for the api. * #param object config The application's configuration. * #param object db The database handler. * #return void */ var clientModel = function ( opts, config, db ) { this.opts = opts; this.config = config; this.db = db; }; /** * Get a list of items. * * #param function cb Callback function. * #return void */ clientModel.prototype.getList = function( cb ) { this.db.query( "SELECT FROM " + this.db.escape("client"), function ( err, rows, fields ) { if( err.code && err.fatal ) { cb( { message: "SQL error locating client." }); return; } if(! rows.length ) { cb( { message: "Unable to locate client." }); return; } cb( false, rows, fields ); }); }; /** * Default http request for getting a list of items. * * * #param object req The http request. * #param object res The http response. * #return void */ clientModel.prototype.httpGetList = function ( req, res ) { this.getList( function ( err, rows, fields ) { res.end("Got a list"); }); } // - Append model to output. module = module.exports = clientModel; Basically node express framework calls httpGetList and "this" doesn't have getList due to "this" being express due to context, is there any way of improving my code in order to do this correctly, I am guessing if it got to the this.getList then this.db would also be out of context? Any help appreciated.
You can bind your functions to an object, so that no matter how they get called, this will be as you expect it. You can find more information here. You can bind the methods in your constructor. The underscore library has an useful bindAll method to help you with that.
I suggest you make the instance inside the module and export the functions that handle the requests. /** * Exports. * * #param object opts The options for the api. * #param object config The application's configuration. * #param object db The database handler. * #return void */ module = module.exports = function ( opts, config, db ) { var instance = new clientModel( opts, config, db ); return { /** * Default http request for getting a list of items. * * * #param object req The http request. * #param object res The http response. * #return void */ httpGetList : function ( req, res ) { instance.getList( function ( err, rows, fields ) { res.end("Got a list"); }); } }; };