Manual Reference Source Test

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;