services/game-tracking-service.js

/**
 * AngularJS Service for tracking player game related information. It is
 * possible to add to the values being tracked by default.
 *
 * @module gameTrackingService
 * @see https://docs.angularjs.org/api/ng/type/angular.Module#service
 */
angular.module('tgaApp').service('gameTrackingService', [
  function gameTrackingService() {
    /**
     * Stored default keys/values for tracking data.
     *
     * @private
     * @member {Object} defaultValues
     */
    const defaultValues = {
      score: 0,
      questionsAsked: 0,
      questionsCorrect: 0,
      sessionStartTime: Date.now(),
      pausedTime: 0,
      pausedStartTime: 0,
    };

    /**
     * Stored game tracking data.
     *
     * @private
     * @member {?Object} currentValues
     */
    let currentValues = null;

    /**
     * Resets stored tracking data to stored default values.
     */
    this.reset = () => {
      const defaultStr = angular.toJson(defaultValues);
      currentValues = angular.fromJson(defaultStr);
      currentValues.sessionStartTime = Date.now();
    };

    /**
     * Used internally to ensure that stored tracking data is a useful object.
     * Resets data to stored defaults if necessary.
     *
     * @private
     * @method checkInit
     */
    const checkInit = () => {
      if (!currentValues) {
        this.reset();
      }
    };

    /**
     * Get stored tracking data.
     *
     * @returns {Object}
     */
    this.get = () => {
      checkInit();
      return currentValues;
    };

    /**
     * Add tracking key with initial value to data object and defaults object.
     *
     * @param {string} key
     * @param {*} initVal
     */
    this.addKey = (key, initVal) => {
      checkInit();
      defaultValues[key] = initVal;
      currentValues[key] = initVal;
    };

    /**
     * Increment a stored data key by a given value.
     *
     * @param {string} key
     * @param {number} val
     */
    this.increment = (key, val) => {
      checkInit();
      currentValues[key] += val;
    };

    /**
     * Set a stored data key to a given value (do not modify stored defaults)
     *
     * @param {string} key
     * @param {number} val
     */
    this.update = (key, val) => {
      checkInit();
      currentValues[key] = val;
    };
  },
]);