Skip to content

Commit

Permalink
Improved TS, generalized getUnifiedData
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
the-bay-kay committed Oct 13, 2023
1 parent 2963e12 commit 36cfff6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 38 deletions.
12 changes: 8 additions & 4 deletions www/js/diary/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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!");
Expand Down Expand Up @@ -356,7 +360,7 @@ angular.module('emission.main.diary.services', ['emission.plugin.logger',
return trip_gj_list;
});
}
});
});
}

var localCacheReadFn = timeline.updateFromDatabase;
Expand Down
13 changes: 7 additions & 6 deletions www/js/diary/timelineHelper.ts
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -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);
}
Expand Down
7 changes: 4 additions & 3 deletions www/js/survey/enketo/enketoHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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));
}
53 changes: 28 additions & 25 deletions www/js/unifiedDataLoader.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
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<dataObj>, list2: Array<dataObj>) {
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;
});
};

// TODO: generalize to iterable of promises
const combinedPromise = function(localPromise, remotePromise, combiner) {
const combinedPromise = function(localPromise: Promise<any>, remotePromise: Promise<any>,
combiner: (list1: Array<any>, list2: Array<any>) => Array<any>) {
return new Promise(function(resolve, reject) {
var localResult = [];
var localError = null;
Expand Down Expand Up @@ -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<any>;
}
Expand All @@ -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<any>) {
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);
};

0 comments on commit 36cfff6

Please sign in to comment.