src/services/AnalyticsService.js
import Client from '../Client';
import JsonApiService from './JsonApiService';
import Insight from '../helpers/Insight';
import {
hasToken,
isA,
isRequired,
validate,
} from '../utilities/ValidationUtility';
/**
* Service handling Analytics calls with specific endpoints.
*
*/
class AnalyticsService extends JsonApiService {
/**
* Gets the current location using the browser navigator.geolocation.getCurrentPosition method
*
* @return {Promise<any>} - Promise object that returns success or failure
*/
getCurrent() {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition((location) => {
resolve(location.coords);
}, (err) => {
reject(err.message);
}, { timeout: 10000 }).catch(reason => reject(reason)); // errors out on timeout after 10 seconds
});
}
/**
* @override
* Call a GET request expecting JSON API information.
*
* @throws {Clinical6Error} - If missing token or missing required parameters
* @param {Object} [params] - Parameters used to get information from server (such as name)
* @param {String} [params.name] - name of the analyticsMetric
* @param {String} [cacheMode] - Override the caching method for this call
* @return {Promise<AnalyticsMetric>}
* - Promise object that returns one AnalyticsMetric
*
* @example
* import { analyticsService } from 'clinical6';
*
* // You will be able to access these analyticsMetrics using the `getMetrics` method. You must
* // provide the name of the analyticMetric
* analyticsService.getMetrics({ name: 'accepted_users' }).then(analyticsMetric => console.log(analyticsMetric));
*/
getMetrics(params = {}, cacheMode = undefined) {
validate('AnalyticsService.getMetrics',
hasToken());
const _params = { type: 'analytics__metrics' };
if (params.name) { _params.name = params.name; }
return super.get(_params, { key: 'name', cacheMode });
}
/**
* Posts insights tracking to the Clinical6 platform
*
* @throws {Clinical6Error} - If missing token or missing required parameters
* @param {!String} action - The action that triggers the track insights event,
* @param {!String} section - The section of the application that triggers the
* application,
* @param {?String} [value] - The specific element Id for the given section to
* track.
* @param {?String} [label] - The name/text the user sees for the value being
* tracked.
* @param {?String} [triggeredAt] - The timestamp for when the event occurred. If this
* parameter is not found, it defaults to the
* timestamp of the request,
* @param {?String} [brandId] - The brand associated with the section/value,
* @param {?Object} [location={}] - Object including the following location-based fields
* @param {?Float} [location.latitude] - latitude in the location
* @param {?Float} [location.longitude] - longitude in the location
* @return {Promise<any>} - Promise object that returns success or failure
*
* @example
* import { analyticsService } from 'clinical6';
*
* analyticsService.postInsights('save', 'Acronyms');
* analyticsService.postInsights('save', 'Acronyms');
* analyticsService.postInsights('save', 'Acronyms', 'value23', 'label', 53,
* {latitude: 53.20483, longitude: 78.2840});
*/
postInsights(action, section, value, label, triggeredAt, brandId,
location = {}) {
validate('Clinical6 postInsights',
hasToken(),
isRequired({ action, section }),
isA({ action, section }, 'string'));
const insight = new Insight(action, section, value, label, triggeredAt, brandId, location);
return new Promise((resolve, reject) => {
if (Client.instance.config.track.gps) {
this.getCurrent()
.then(
response => resolve(response),
err => reject(err)
)
.catch(reason => reject(reason));
} else {
resolve(location);
}
}).then(_location => new Promise((resolve, reject) => {
insight.location = _location;
Client.instance.fetch('/api/v2/insights/track', 'post', insight)
.then(
response => resolve(response),
err => reject(err)
)
.catch(reason => reject(reason));
}));
}
}
export default AnalyticsService;