src/services/LocationService.js
import JsonApiService from './JsonApiService';
import Client from '../Client';
import Location from '../helpers/Location';
import { validate, hasToken, isRequired } from '../utilities/ValidationUtility';
/**
* Service handling Location calls.
*
* Clinical6 has a couple of built-in methods that make it easy to get a user's current location,
* and update the location to the server.
*/
class LocationService extends JsonApiService {
/**
* Update type to be locations
*/
constructor() {
super('locations',
{
title: 'LocationService',
obj: 'location',
tokenRequired: ['delete', 'get', 'getChildren', 'insert', 'update']
});
}
/**
* @override
* Call a DELETE request on the main obj.type expecting JSON API information.
*
* This method is not supported by Location
*
* @param {Object} object - Object in which to delete
* @param {String} [cacheMode] - Override the caching method for this call
* @return {Promise} - Message
*/
delete(object, cacheMode = undefined) {
return super.delete(object, { cacheMode });
}
/**
* @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 id)
* @param {Number} [params.id] - Id of the location
* @param {String} [cacheMode] - Override the caching method for this call
* @return {Promise<Location[] | Location>}
* - Promise object that returns one location or a key:location hashtable
*
* @example
* import { locationService } from 'clinical6';
*
* // You will be able to access these locations using the `get` method.
* locationService.get().then(locations => console.log(locations));
*
*/
get(params = {}, cacheMode = undefined) {
return super.get(params, { cacheMode });
}
/**
* Gets the current location using the browser navigator.geolocation.getCurrentPosition method
*
* @return {Promise} - Promise object that returns success or failure
*
* @example
* import { locationService } from 'clinical6';
*
* // gets a Promise the current location with the specific latitude or longitude
* var location;
* locationService.getCurrent().then((location) => location = data );
*/
getCurrent() {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition((location) => {
resolve(location.coords);
}, (err) => {
reject(err.message);
}, { timeout: 10000 }); // 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 offset)
* @param {Object} [params.sort] - Param passed to sort timezones. Can either be 'offset' or '-offset'
* @param {String} [cacheMode] - Override the caching method for this call
* @return {Promise<Timezone[]>} - Promise object that returns a key:timezone hashtable
*
* @example
* import { locationService } from 'clinical6';
*
* // You will be able to access these timezones using the `getTimezones` method.
* locationService.getTimezones().then(timezones => console.log(timezones));
*
* // Additionally, you can pass params.offset to sort the returned timezones
* locationService.getTimezones({ sort: '-offset' }).then(timezones => console.log(timezones));
*/
getTimezones(params = {}, cacheMode = undefined) {
validate('LocationService.getTimezones',
hasToken());
const sort = params.sort ? `/${params.sort}` : '';
const url = `/v3/timezones${sort}`;
return super.get(params, { url, cacheMode });
}
/**
* @override
* Call a POST request on the main obj.type expecting JSON API information.
*
* @param {Object} [location] - Parameters used to get information from server (such as id)
* @param {String} [cacheMode] - Override the caching method for this call
* @return {Promise<Location>} - Inserted location
*
* @example
* import { Location, locationService } from 'clinical6';
* const location = new Location({...});
*
* // you can insert a location using the `insert` method.
* locationService.insert(location).then(location => console.log(location));
*
* // you could also just call `save` on the location if it doesn't have an id, which will also
* // invoke the `insert` method
* location.save();
*/
insert(location = undefined, cacheMode = undefined) {
return super.insert(location, { cacheMode });
}
/**
* Update user location
*
* @throws {Clinical6Error} - If missing token or missing required parameters
* @param {Object} location - Object including the following location-based fields:
* @param {Float} location.latitude - Latitude
* @param {Float} location.longitude - Longitude
* @param {String} location.country - Country
* @param {String} location.state - State
* @param {String} location.city - City
* @param {String} location.street - Street
* @param {String} location.zip_code - Zip Code
* @return {Promise} - Promise object that returns success or failure
*
* @example
* import { locationService } from 'clinical6';
*
* // gets a Promise the current location with the specific latitude or longitude
* var location;
* locationService.getCurrent().then((location) => location = data );
*
* // gets a Promise that posts a location to the server
* locationService.updateLocation(location);
*/
insertV2(location) {
validate('Clinical6 insertV2',
hasToken(),
isRequired({ location }));
const data = new Location(location);
return new Promise((resolve, reject) => {
Client.instance.fetch('/api/devices/update_location', 'post', { location: data }).then(
response => resolve(response),
err => reject(err)
);
});
}
/**
* Calls insertV2 method with the current location latitude and longitude.
*
* @return {Promise} - Promise object that returns success or failure
*
* @example
* import { locationService } from 'clinical6';
*
* // gets a Promise that posts the current location to the server
* locationService.updateCurrentLocation();
*/
insertCurrent() {
validate('Clinical6 insertCurrent',
hasToken());
return new Promise((resolve, reject) => {
this.getCurrent().then((location) => {
this.insertV2({ latitude: location.latitude, longitude: location.longitude }).then(
success => (resolve(success)),
err => (reject(err))
);
},
err => (Error(`unable to updateCurrentLocation at this time: ${err}`)))
.catch(err => reject(err));
});
}
/**
* @override
* Call a PATCH request on the main obj.type expecting JSON API information.
*
* This method is not supported by Location
* @param {Location} location - Location object in which to update
* @param {Object} [options] - Override the caching method for this call
* @param {String} [options.cacheMode] - Override the caching method for this call
* @return {Promise} - Message
*
* @example
* import { Location, locationService } from 'clinical6';
* const location = new Location({...});
*
* // you can update a location using the `update` method.
* locationService.update(location).then(location => console.log(location));
*
* // you could also just call `save` on the location if it has an id, which will also
* // invoke the `update` method
* location.save();
*/
async update(location, options = {}) {
validate('LocationService.update',
hasToken(),
isRequired({ location }));
return super.update(location, options);
}
}
export default LocationService;