Commit dcee9d35 authored by Pithon Kabiro's avatar Pithon Kabiro
Browse files

Edit function: callback function that draws chart

Check the structure of the arrays of observations + metadata. Throw
errors if there is a problem fetching metadata and observations
parent bee78fb8
......@@ -228,18 +228,35 @@ const drawChartUsingSelectedOptions = async function () {
)
);
// If there is an error in fetching metadata + observations (Case 1: raw observations)
// the returned array will have this structure: [[undefined, undefined], undefined]
// Note that the second element is not an array as we would expect but is a
// a single `undefined` value
if (typeof observationsRawPlusMetadataArr[0][0] === "undefined") {
throw new Error(
`There was a problem in fetching metadata and observations`
);
}
// If there is an error in fetching metadata + observations (Case 2: temperature difference, dT)
// a single `undefined` value instead of an array (as we would expect) will be returned
if (typeof observationsTempDiffPlusMetadataArr === "undefined")
throw new Error(
`There was a problem in calculating the temperature difference (dT).\nThis is most likely due to a problem in fetching metadata and observations`
);
// Extract the combined arrays for observations and metadata / raw observations
const [observationsRawNestedArr, metadataTempDiffNestedArr] =
const [observationsRawNestedArr, metadataRawNestedArr] =
observationsRawPlusMetadataArr;
// Extract the combined arrays for observations and metadata / temperature difference (dT)
const [observationsNestedComputedArr, metadataNestedComputedArr] =
const [observationsTempDiffNestedArr, metadataTempDiffNestedArr] =
observationsTempDiffPlusMetadataArr;
// Create a combined array of observations and metadata
const observationsPlusMetadataCombined = [
[...observationsRawNestedArr, ...observationsNestedComputedArr],
[...metadataTempDiffNestedArr, ...metadataNestedComputedArr],
[...observationsRawNestedArr, ...observationsTempDiffNestedArr],
[...metadataRawNestedArr, ...metadataTempDiffNestedArr],
];
const [observationsComboNestedArr, metadataComboNestedArr] =
......@@ -384,6 +401,9 @@ const drawChartUsingSelectedOptions = async function () {
}
} catch (err) {
console.error(err);
// Display a dialog window with the error message
alert(err);
} finally {
// Enable the 'draw chart' button
enableDrawChartButton();
......
......@@ -252,58 +252,67 @@ const extractObservationValuesWithinMonthInterval = function (
samplingRate,
calendarMonthStr
) {
// Extract the year and month digits from the calendar month string
const [yearNum, monthNum] =
extractMonthYearDigitsFromCalendarMonthString(calendarMonthStr);
try {
// Extract the year and month digits from the calendar month string
const [yearNum, monthNum] =
extractMonthYearDigitsFromCalendarMonthString(calendarMonthStr);
// All the months start on the first
const startDateStr = `${calendarMonthStr}-01`;
// All the months start on the first
const startDateStr = `${calendarMonthStr}-01`;
if (monthNum < 1 || monthNum > 12) {
throw new Error("The specified digit for the month of the year is invalid");
}
// February
else if (monthNum === 2) {
// Leap year
if (checkIfLeapYear(yearNum)) {
if (monthNum < 1 || monthNum > 12) {
throw new Error(
"The specified digit for the month of the year is invalid"
);
}
// February
else if (monthNum === 2) {
// Leap year
if (checkIfLeapYear(yearNum)) {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-29`
);
}
// Non-leap year
else {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-28`
);
}
}
// Months with 30 days
else if (
monthNum === 4 ||
monthNum === 6 ||
monthNum === 9 ||
monthNum === 11
) {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-29`
`${calendarMonthStr}-30`
);
}
// Non-leap year
// Months with 31 days
else {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-28`
`${calendarMonthStr}-31`
);
}
}
// Months with 30 days
else if (
monthNum === 4 ||
monthNum === 6 ||
monthNum === 9 ||
monthNum === 11
) {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-30`
);
}
// Months with 31 days
else {
return extractObservationValuesWithinDatesInterval(
obsArray,
samplingRate,
startDateStr,
`${calendarMonthStr}-31`
} catch (err) {
// Rethrow errors from `getIndexOfStartTimestamp` or `getIndexOfEndTimestamp` functions
throw new Error(
`${err.message} \nCurrently, the monthly aggregation does not support partial calendar months`
);
}
};
......
......@@ -175,6 +175,16 @@ export const calculateVorlaufMinusRuecklaufTemperature = async function (
bldgDataPtSamplingRateNestedArr
);
// If there is an error in fetching metadata + observations,
// the returned array will have this structure: [[undefined, undefined], undefined]
// Note that the second element is not an array as we would expect but is a
// a single `undefined` value
if (typeof observationsPlusMetadata[0][0] === "undefined") {
throw new Error(
`There was a problem in calculating the temperature difference (dT).\nThis is most likely due to a problem in fetching metadata and observations`
);
}
// dT observations (timestamp + value)
const vorlaufMinusRuecklaufTemperatureObs =
calculateVorlaufMinusRuecklaufTemperatureObservations(
......
......@@ -24,44 +24,73 @@ const createObservationsUrl = function (baseUrl, datastreamID) {
return `${baseUrl}/Datastreams(${datastreamID})/Observations`;
};
/**
* Perform a GET request to fetch a single Datastream using the Axios library
*
* @param {String} urlDatastream A URL that fetches a single Datastream from an STA instance
* @returns {Promise} A promise that contains the Datastream metadata when fulfilled
*/
const getDatastream = function (urlDatastream) {
return axios.get(urlDatastream);
};
/**
* Perform a GET request using the Axios library
* @param {String} urlObservations A URL that fetches Observations from an STA instance
* @param {Object} urlParamObj The URL parameters to be sent together with the GET request
* @returns {Promise} A promise that contains the first page of results when fulfilled
*/
const performGetRequestUsingAxios = function (urlObservations, urlParamObj) {
const getObservations = function (urlObservations, urlParamObj) {
return axios.get(urlObservations, {
params: urlParamObj,
});
};
/**
* Retrieve the metadata for a single datastream
* Extract the metadata from a single datastream
* @async
* @param {String} urlDatastream A URL that fetches a Datastream from an STA instance
* @returns {Promise} A promise that contains a metadata object for a Datastream when fulfilled
*/
const getMetadataFromSingleDatastream = async function (urlDatastream) {
const extractMetadataFromSingleDatastream = async function (urlDatastream) {
try {
// Extract properties of interest
const {
data: { description, name, unitOfMeasurement },
} = await performGetRequestUsingAxios(urlDatastream);
} = await getDatastream(urlDatastream);
return { description, name, unitOfMeasurement };
} catch (err) {
console.error(err);
// Server responded with status code outside of 2xx range
if (err.response) {
throw new Error(
`The request to fetch Datastream metadata was made but the server responded with: \n${err.message}`
);
}
// Request was made but no response was received
else if (err.request) {
throw new Error(
`The request to fetch Datastream metadata was made but no response was received: \n${err.message}`
);
}
// Problem with setting up the request
else {
throw new Error(
`There was a problem setting up the request to fetch Datastream metadata: \n${err.message}`
);
}
}
};
/**
* Retrieve metadata from multiple datastreams
* Extract the metadata from multiple datastreams
* @async
* @param {Array} datastreamsUrlArr An array that contains N Datastream URL strings
* @returns {Promise} A promise that contains an array of N Datastream metadata objects when fulfilled
*/
const getMetadataFromMultipleDatastreams = async function (datastreamsUrlArr) {
const extractMetadataFromMultipleDatastreams = async function (
datastreamsUrlArr
) {
try {
// Array to store our final result
const datastreamMetadataArr = [];
......@@ -69,7 +98,7 @@ const getMetadataFromMultipleDatastreams = async function (datastreamsUrlArr) {
// Use for/of loop - we need to maintain the order of execution of the async operations
for (const datastreamUrl of datastreamsUrlArr) {
// Metadata from a single Datastream
const datastreamMetadata = await getMetadataFromSingleDatastream(
const datastreamMetadata = await extractMetadataFromSingleDatastream(
datastreamUrl
);
datastreamMetadataArr.push(datastreamMetadata);
......@@ -109,7 +138,24 @@ const combineResultsFromAllPages = async function (httpGetRequestPromise) {
return lastSuccess;
}
} catch (err) {
console.error(err);
// Server responded with status code outside of 2xx range
if (err.response) {
throw new Error(
`The request to fetch Observations was made but the server responded with: \n${err.message}`
);
}
// Request was made but no response was received
else if (err.request) {
throw new Error(
`The request to fetch Observations was made but no response was received: \n${err.message}`
);
}
// Problem with setting up the request
else {
throw new Error(
`There was a problem setting up the request to fetch Observations: \n${err.message}`
);
}
}
};
......@@ -208,7 +254,7 @@ const getMetadataPlusObservationsFromSingleOrMultipleDatastreams =
// Promise objects - Observations
const observationsPromisesArr = observationsUrlArr.map((obsUrl) =>
extractCombinedObservationsFromAllPages(
performGetRequestUsingAxios(obsUrl, urlParamObj)
getObservations(obsUrl, urlParamObj)
)
);
......@@ -218,7 +264,7 @@ const getMetadataPlusObservationsFromSingleOrMultipleDatastreams =
);
// Metadata array
const metadataArr = await getMetadataFromMultipleDatastreams(
const metadataArr = await extractMetadataFromMultipleDatastreams(
datastreamsUrlArr
);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment