I needed to update a class in Node.js that parses the response from a new weather API endpoint but still preserves the same object structure and key values from having been using the old weather API endpoint. The return value from the class' main method should be an array of eight objects, each representing data from a given day of the week, including hi
and low
temps, and a day
and night
object.
The data from the new API response is structured as follows with arrays of lengths 8 and 16:
const apiResponse = {
dayOfWeek: ['Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
calendarDayTemperatureMax: [57, 59, 53, 47, 42, 44, 42, 43],
calendarDayTemperatureMin: [39, 40, 40, 37, 33, 31, 31, 30]
validTimeLocal: ['2024-02-09T07:00:00-0500', '2024-02-10T07:00:00-0500', '2024-02-11T07:00:00-0500', '2024-02-12T07:00:00-0500', '2024-02-13T07:00:00-0500', '2024-02-14T07:00:00-0500', '2024-02-15T07:00:00-0500', '2024-02-16T07:00:00-0500'],
daypart:[{
dayOrNight: ['D', 'N', 'D', 'N', 'D', 'N', 'D', 'N', 'D', 'N', 'D', 'N', 'D', 'N', 'D', 'N'],
daypartName: ['Today', 'Tonight', 'Tomorrow', 'Tomorrow night', 'Sunday', 'Sunday night', 'Monday', 'Monday night', 'Tuesday', 'Tuesday night', 'Wednesday', 'Wednesday night', 'Thursday', 'Thursday night', 'Friday', 'Friday night']
temperature: [57, 40, 59, 45, 51, 37, 47, 35, 41, 31, 44, 31, 42, 30, 43, 29],
iconCode: [32, 29, 26, 27, 26, 27, 39, 5, 16, 29, 30, 29, 30, 29, 30, 29]
}]
}
The old weekly weather forecast class:
module.exports = class Weekly extends Feed {
constructor () {
super()
this.desiredFields = ['daypart_name', 'temp', 'icon_code', 'fcst_valid_local']
this.fieldMap = {
'fcst_valid_local': 'date',
'daypart_name': 'day_part'
}
}
/**
* Accepts Api results and request; formats feed for API output
*
* @param {Api} apiResponse
* @param {Request} request
*/
getDayPartFields (obj) {
let fields = _.pick(obj, this.desiredFields)
return Feed.mapFields(this.fieldMap, fields)
}
generateFeed (apiResponse, request) {
let formattedResponse = apiResponse.forecasts.map( obj => {
let { day, night, max_temp, min_temp} = obj
let dayObject = this.getDayPartFields(day)
let nightObject = this.getDayPartFields(night)
return { hi: max_temp, lo: min_temp, day: dayObject, night: nightObject }
})
let feed = this.getBaseFeed(request, formattedResponse)
this.setFeed(feed)
}
}
My updated weekly weather forecast class looks like this:
module.exports = class Weekly extends Feed {
constructor () {
super()
this.desiredFields = ['daypartName', 'temp', 'icon_code', 'validTimeLocal']
this.fieldMap = {
'validTimeLocal': 'date',
'daypartName': 'day_part'
}
}
/**
* Accepts Api results and request; formats feed for API output
*
* @param {Api} apiResponse
* @param {Request} request
*/
generateFeed (apiResponse, request) {
let formattedResponse = apiResponse.dayOfWeek.map((_, idx) => {
const dayIndex = idx * 2;
return {
'hi': apiResponse.calendarDayTemperatureMax[idx],
'lo': apiResponse.calendarDayTemperatureMin[idx],
'day': {
'daypart': apiResponse.daypart[0].daypartName[dayIndex],
'temp': apiResponse.daypart[0].temperature[dayIndex],
'icon_code': apiResponse.daypart[0].iconCode[dayIndex],
'date': apiResponse.validTimeLocal[idx]
},
'night': {
'daypart': apiResponse.daypart[0].daypartName[dayIndex + 1],
'temp': apiResponse.daypart[0].temperature[dayIndex + 1],
'icon_code': apiResponse.daypart[0].iconCode[dayIndex + 1],
'date': apiResponse.validTimeLocal[idx]
}
};
});
let feed = this.getBaseFeed(request, formattedResponse)
this.setFeed(feed)
}
}
The properties in the constructor method were left over from the previous implementation, but I updated a couple of the values to correlate with the new API response. There were also a couple of helper methods with I deleted, each for populating the values in the day
and night
objects in the formattedResponse
.
Would it be better to have a couple of helper methods here? Also, do I need to keep what's inside the constructor method? This was actually quite a bit of fun to solve, but I would welcome any suggestions for optimization, thanks!