From 6988d17c03aeea98ab6f67a4af1e0c422c05a178 Mon Sep 17 00:00:00 2001 From: Katie Rischpater <98350084+the-bay-kay@users.noreply.github.com> Date: Fri, 13 Oct 2023 11:18:03 -0700 Subject: [PATCH] Improved TS, gneeralized getUnifiedData - Generalized getUnified functions into one method that takes a higher order function as input, and uses that to fetch required data. - Updated calls to the getUnified functions - Added an interface for the combineWithDedup method, because it requires objects with the 'metadata.writets' property to run - Updated other unifiedDataLoader functions so the parameters were appropriately typed --- www/js/diary/services.js | 12 ++++--- www/js/diary/timelineHelper.ts | 13 +++---- www/js/survey/enketo/enketoHelper.ts | 7 ++-- www/js/unifiedDataLoader.ts | 53 +++++++++++++++------------- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/www/js/diary/services.js b/www/js/diary/services.js index 792c640a3..e0f1b5349 100644 --- a/www/js/diary/services.js +++ b/www/js/diary/services.js @@ -4,7 +4,7 @@ import angular from 'angular'; import { SurveyOptions } from '../survey/survey'; import { getConfig } from '../config/dynamicConfig'; import { getRawEntries } from '../commHelper'; -import { getUnifiedSensorDataForInterval, getUnifiedMessagesForInterval } from '../unifiedDataLoader' +import { getUnifiedDataForInterval } from '../unifiedDataLoader' angular.module('emission.main.diary.services', ['emission.plugin.logger', 'emission.services']) @@ -232,7 +232,9 @@ angular.module('emission.main.diary.services', ['emission.plugin.logger', Logger.log("About to pull location data for range " + moment.unix(tripStartTransition.data.ts).toString() + " -> " + moment.unix(tripEndTransition.data.ts).toString()); - return getUnifiedSensorDataForInterval("background/filtered_location", tq).then(function(locationList) { + const getSensorData = window['cordova'].plugins.BEMUserCache.getSensorDataForInterval; + return getUnifiedDataForInterval("background/filtered_location", tq, getSensorData) + .then(function(locationList) { if (locationList.length == 0) { return undefined; } @@ -304,7 +306,9 @@ angular.module('emission.main.diary.services', ['emission.plugin.logger', } Logger.log("about to query for unprocessed trips from " +moment.unix(tq.startTs).toString()+" -> "+moment.unix(tq.endTs).toString()); - return getUnifiedMessagesForInterval("statemachine/transition", tq) + + const getMessageMethod = window['cordova'].plugins.BEMUserCache.getMessagesForInterval; + return getUnifiedDataForInterval("statemachine/transition", tq, getMessageMethod) .then(function(transitionList) { if (transitionList.length == 0) { Logger.log("No unprocessed trips. yay!"); @@ -356,7 +360,7 @@ angular.module('emission.main.diary.services', ['emission.plugin.logger', return trip_gj_list; }); } - }); + }); } var localCacheReadFn = timeline.updateFromDatabase; diff --git a/www/js/diary/timelineHelper.ts b/www/js/diary/timelineHelper.ts index c4d517c40..287484a7a 100644 --- a/www/js/diary/timelineHelper.ts +++ b/www/js/diary/timelineHelper.ts @@ -1,8 +1,7 @@ import moment from "moment"; -import { getAngularService } from "../angular-react-helper"; import { displayError, logDebug } from "../plugin/logger"; import { getBaseModeByKey, getBaseModeOfLabeledTrip } from "./diaryHelper"; -import { getUnifiedMessagesForInterval } from "../unifiedDataLoader"; +import { getUnifiedDataForInterval} from "../unifiedDataLoader"; import i18next from "i18next"; const cachedGeojsons = new Map(); @@ -149,11 +148,13 @@ export function getLocalUnprocessedInputs(pipelineRange, labelsFactory, notesFac */ export function getAllUnprocessedInputs(pipelineRange, labelsFactory, notesFactory) { const tq = getUnprocessedInputQuery(pipelineRange); - const labelsPromises = labelsFactory.MANUAL_KEYS.map((key) => - getUnifiedMessagesForInterval(key, tq).then(labelsFactory.extractResult) + const getMethod = window['cordova'].plugins.BEMUserCache.getMessagesForInterval; + + const labelsPromises = labelsFactory.MANUAL_KEYS.map((key) => + getUnifiedDataForInterval(key, tq, getMethod).then(labelsFactory.extractResult) ); - const notesPromises = notesFactory.MANUAL_KEYS.map((key) => - getUnifiedMessagesForInterval(key, tq).then(notesFactory.extractResult) + const notesPromises = notesFactory.MANUAL_KEYS.map((key) => + getUnifiedDataForInterval(key, tq, getMethod).then(notesFactory.extractResult) ); return getUnprocessedResults(labelsFactory, notesFactory, labelsPromises, notesPromises); } diff --git a/www/js/survey/enketo/enketoHelper.ts b/www/js/survey/enketo/enketoHelper.ts index aecf3af93..c35dd03a3 100644 --- a/www/js/survey/enketo/enketoHelper.ts +++ b/www/js/survey/enketo/enketoHelper.ts @@ -3,7 +3,7 @@ import { Form } from 'enketo-core'; import { XMLParser } from 'fast-xml-parser'; import i18next from 'i18next'; import { logDebug } from "../../plugin/logger"; -import { getUnifiedMessagesForInterval } from "../../unifiedDataLoader"; +import { getUnifiedDataForInterval} from "../../unifiedDataLoader"; export type PrefillFields = {[key: string]: string}; @@ -110,6 +110,7 @@ const _getMostRecent = (answers) => { export function loadPreviousResponseForSurvey(dataKey: string) { const tq = window['cordova'].plugins.BEMUserCache.getAllTimeQuery(); logDebug("loadPreviousResponseForSurvey: dataKey = " + dataKey + "; tq = " + tq); - return getUnifiedMessagesForInterval(dataKey, tq) - .then(answers => _getMostRecent(answers)) + const getMethod = window['cordova'].plugins.BEMUserCache.getSensorDataForInterval; + return getUnifiedDataForInterval(dataKey, tq, getMethod) + .then(answers => _getMostRecent(answers)); } diff --git a/www/js/unifiedDataLoader.ts b/www/js/unifiedDataLoader.ts index 32c12ea3e..87ae3380d 100644 --- a/www/js/unifiedDataLoader.ts +++ b/www/js/unifiedDataLoader.ts @@ -1,11 +1,22 @@ import { logInfo } from './plugin/logger' import { getRawEntries } from './commHelper'; -// Helper Functions for the getUnified methods. -const combineWithDedup = function(list1, list2) { +interface dataObj { + data: any; + metadata: { + plugin: string; + write_ts: number; + platform: string; + read_ts: number; + key: string; + type: string; + } +} +const combineWithDedup = function(list1: Array, list2: Array) { const combinedList = list1.concat(list2); return combinedList.filter(function(value, i, array) { - const firstIndexOfValue = array.findIndex(function(element, index, array) { + const firstIndexOfValue = array.findIndex(function(element) { + console.log(`==> Element: ${JSON.stringify(element, null, 4)} `); return element.metadata.write_ts == value.metadata.write_ts; }); return firstIndexOfValue == i; @@ -13,7 +24,8 @@ const combineWithDedup = function(list1, list2) { }; // TODO: generalize to iterable of promises -const combinedPromise = function(localPromise, remotePromise, combiner) { +const combinedPromise = function(localPromise: Promise, remotePromise: Promise, + combiner: (list1: Array, list2: Array) => Array) { return new Promise(function(resolve, reject) { var localResult = []; var localError = null; @@ -59,6 +71,8 @@ const combinedPromise = function(localPromise, remotePromise, combiner) { }) } +// This is an generalized get function for data; example uses could be with +// the getSensorDataForInterval or getMessagesForInterval functions. interface serverData { phone_data: Array; } @@ -67,24 +81,13 @@ interface tQ { startTs: number; endTs: number; } -// TODO: Generalize this to work for both sensor data and messages -// Do we even need to separate the two kinds of data? -export const getUnifiedSensorDataForInterval = function(key: string, tq: tQ) { - const localPromise = window['cordova'].plugins.BEMUserCache.getSensorDataForInterval(key, tq, true); - const remotePromise = getRawEntries([key], tq.startTs, tq.endTs) - .then(function(serverResponse: serverData) { - console.log(`\n\n\n TQ : ${JSON.stringify(tq)}`) - return serverResponse.phone_data; - }); - return combinedPromise(localPromise, remotePromise, combineWithDedup); -}; - -export const getUnifiedMessagesForInterval = function(key: string, tq: tQ) { - const localPromise = window['cordova'].plugins.BEMUserCache.getMessagesForInterval(key, tq, true); - const remotePromise = getRawEntries([key], tq.startTs, tq.endTs) - .then(function(serverResponse: serverData) { - console.log('==>', JSON.stringify(tq.endTs), ':',typeof tq.endTs); - return serverResponse.phone_data; - }); - return combinedPromise(localPromise, remotePromise, combineWithDedup); - } +export const getUnifiedDataForInterval = function(key: string, tq: tQ, + getMethod: (key: string, tq: tQ, flag: boolean) => Promise) { + const test = true; + const localPromise = getMethod(key, tq, test); + const remotePromise = getRawEntries([key], tq.startTs, tq.endTs) + .then(function(serverResponse: serverData) { + return serverResponse.phone_data; + }); + return combinedPromise(localPromise, remotePromise, combineWithDedup); +}; \ No newline at end of file