I have a JS object with multiple arrays inside it. Each array has a "message" key and i have created a few lines of code that are able to filter out the specific arrays who’s message value contain the word "INFO"
My goal is to create a new object i am calling finalLogDataObject which will contain only the filtered message keys
Let me give you an example of what I am trying to achieve
[{"id":3,"key1":"value1","key2":"value2"},{"id":2,"key1":"value1","key2":"value2"},{"id":1,"key1":"value1","key2":"value2"}]
And the original object is
[
{
"eventId": "12345",
"ingestionTime": 1687441551603,
"message": "START RequestId: xxxxxxxxxxxxxxxxxxxxxxx Version: $LATESTn",
"timestamp": 1685441542538
},
{
"eventId": "12345",
"ingestionTime": 1687441551605,
"message": "2023-06-22T13:45:42.539ZtxxxxxxxxxxxxxxxxxxxxxxxtINFOt{"id":3,"key1":"value1","key2":"value2"}n",
"timestamp": 1684441542539
},
{
"eventId": "12324",
"ingestionTime": 1687491551605,
"message": "END RequestId: xxxxxxxxxxxxxxxxxxxxxxxn",
"timestamp": 1687941542540
},
{
"eventId": "76543",
"ingestionTime": 1689441551605,
"message": "REPORT RequestId: xxxxxxxxxxxxxxxxxxxxxxxtDuration: 1.26 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1687491542540
},
{
"eventId": "65754",
"ingestionTime": 1687441951605,
"message": "START RequestId: xxx Version: $LATESTn",
"timestamp": 1687441593428
},
{
"eventId": "76856",
"ingestionTime": 1687941551605,
"message": "2023-06-22T13:45:43.429ZtxxxtINFOt{"id":2,"key1":"value1","key2":"value2"}n",
"timestamp": 1687441543729
},
{
"eventId": "57645",
"ingestionTime": 1687441551605,
"message": "END RequestId: xxxn",
"timestamp":81687441543430
},
{
"eventId": "567465",
"ingestionTime": 1687441851605,
"message": "REPORT RequestId: xxxtDuration: 1.62 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1887441543430
},
{
"eventId": "56476",
"ingestionTime": 1687441551605,
"message": "START RequestId: xxx Version: $LATESTn",
"timestamp": 1687441544359
},
{
"eventId": "56885",
"ingestionTime": 1687441551405,
"message": "2023-06-22T13:45:44.360ZtxxxtINFOt{"id":1,"key1":"value1","key2":"value2"}n",
"timestamp": 1687441544360
},
{
"eventId": "45343",
"ingestionTime": 1644441551605,
"message": "END RequestId: xxxn",
"timestamp": 1687441544362
},
{
"eventId": "34653",
"ingestionTime": 1687441558605,
"message": "REPORT RequestId: xxxtDuration: 1.65 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1687441644362
}
]
So far I have been able to filter out the correct fields containing the INFO
key word and format them from within the map function however I have not been able to concatenate the arrays into a new object correctly. I have promises in the object returned from the map function and am also seeing multiple undefined values as well.
when I console log the variable object finalLogDataObject returned from my map function I am seeing this
[
Promise { undefined },
Promise { { id: 3, key1: 'value1', key2: 'value2' } },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { { id: 2, key1: 'value1', key2: 'value2' } },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { { id: 1, key1: 'value1', key2: 'value2' } },
Promise { undefined },
Promise { undefined }
]
when i console log formattedInfoLogMessages from within the map function i am getting 3 arrays that look exactly how i need them.
console.log('formattedInfoLogMessages: ' + formattedInfoLogMessages)
// formattedInfoLogMessages: {"id":3,"key1":"value1","key2":"value2"}
// formattedInfoLogMessages: {"id":2,"key1":"value1","key2":"value2"}
// formattedInfoLogMessages: {"id":1,"key1":"value1","key2":"value2"}
How do i concat them into one object returned from map?
Here is my JavaScript file
async function handler() {
try {
const initialLogDataObject = [
{
"eventId": "12345",
"ingestionTime": 1687441551603,
"message": "START RequestId: xxxxxxxxxxxxxxxxxxxxxxx Version: $LATESTn",
"timestamp": 1685441542538
},
{
"eventId": "12345",
"ingestionTime": 1687441551605,
"message": "2023-06-22T13:45:42.539ZtxxxxxxxxxxxxxxxxxxxxxxxtINFOt{"id":3,"key1":"value1","key2":"value2"}n",
"timestamp": 1684441542539
},
{
"eventId": "12324",
"ingestionTime": 1687491551605,
"message": "END RequestId: xxxxxxxxxxxxxxxxxxxxxxxn",
"timestamp": 1687941542540
},
{
"eventId": "76543",
"ingestionTime": 1689441551605,
"message": "REPORT RequestId: xxxxxxxxxxxxxxxxxxxxxxxtDuration: 1.26 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1687491542540
},
{
"eventId": "65754",
"ingestionTime": 1687441951605,
"message": "START RequestId: xxx Version: $LATESTn",
"timestamp": 1687441593428
},
{
"eventId": "76856",
"ingestionTime": 1687941551605,
"message": "2023-06-22T13:45:43.429ZtxxxtINFOt{"id":2,"key1":"value1","key2":"value2"}n",
"timestamp": 1687441543729
},
{
"eventId": "57645",
"ingestionTime": 1687441551605,
"message": "END RequestId: xxxn",
"timestamp":81687441543430
},
{
"eventId": "567465",
"ingestionTime": 1687441851605,
"message": "REPORT RequestId: xxxtDuration: 1.62 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1887441543430
},
{
"eventId": "56476",
"ingestionTime": 1687441551605,
"message": "START RequestId: xxx Version: $LATESTn",
"timestamp": 1687441544359
},
{
"eventId": "56885",
"ingestionTime": 1687441551405,
"message": "2023-06-22T13:45:44.360ZtxxxtINFOt{"id":1,"key1":"value1","key2":"value2"}n",
"timestamp": 1687441544360
},
{
"eventId": "45343",
"ingestionTime": 1644441551605,
"message": "END RequestId: xxxn",
"timestamp": 1687441544362
},
{
"eventId": "34653",
"ingestionTime": 1687441558605,
"message": "REPORT RequestId: xxxtDuration: 1.65 mstBilled Duration: 2 mstMemory Size: 128 MBtMax Memory Used: 59 MBtn",
"timestamp": 1687441644362
}
]
let finalLogDataObject = Object.entries(initialLogDataObject).map(async function ([key, item]) {
let logStreamEventMessage = item.message
if (logStreamEventMessage.includes("INFO") === true) {
const formattedLogMessage = (String(logStreamEventMessage)).replace("n", "")
const filterByInfoKeyword = formattedLogMessage.split(/[ INFO ]+/);
const getInfoLogMessages = filterByInfoKeyword[1];
const formattedInfoLogMessages = getInfoLogMessages.replace(/s/g, "");
const parsedInfoLogMessages = JSON.parse(formattedInfoLogMessages);
console.log('formattedInfoLogMessages: ' + formattedInfoLogMessages)
// formattedInfoLogMessages: {"id":3,"key1":"value1","key2":"value2"}
// formattedInfoLogMessages: {"id":2,"key1":"value1","key2":"value2"}
// formattedInfoLogMessages: {"id":1,"key1":"value1","key2":"value2"}
return parsedInfoLogMessages
}
})
// here is where I need the object to be [{"id":3,"key1":"value1","key2":"value2"},{"id":2,"key1":"value1","key2":"value2"},{"id":1,"key1":"value1","key2":"value2"}]
console.log(finalLogDataObject)
// however when i console log i get
// [
// Promise { undefined },
// Promise { { id: 3, key1: 'value1', key2: 'value2' } },
// Promise { undefined },
// Promise { undefined },
// Promise { undefined },
// Promise { { id: 2, key1: 'value1', key2: 'value2' } },
// Promise { undefined },
// Promise { undefined },
// Promise { undefined },
// Promise { { id: 1, key1: 'value1', key2: 'value2' } },
// Promise { undefined },
// Promise { undefined }
// ]
} catch (error) {
console.log(error)
}
}
handler()
Any help on where I am messing this up would be great. Thanks in advance for your time and help!
2
Answers
This produces an array of
Promise
objects:You can
await
those promises withPromise.all
, for example:Or, since the functions aren’t performing any asynchronous operations, just remove the
async
keywords entirely so you’re not unnecessarily usingPromise
objects in the first place:Additionally, you’ll still need to remove the
undefined
entries from the array to produce the result you’re looking for. You can use.filter()
for that, returning only "truthy" objects:I think the best solution here would be to use
reduce
since you’re not only filtering, but expecting an array of a different type. The reason whymap
shouldn’t be used here is because good coding practice would have the result ofmap
being the same size as the array being passed in. (i.e., every item in the array now maps onto an new value).Another point to clarify is that you are referring to, and treating an array as an object. Its not necessary to use the
Object.entries
method, since you’re already holding the data as an array.Keeping in mind the data is held as an array, I’d recommend using the
Array.reduce
method.Also you aren’t doing any asynchronous operations in your callback, so you don’t need to indicate the callback as an
async
. In fact, it simplifies the solution because you won’t get a bunch of Promises.If you plan to implement asynchronous operations in the future, lookup promise awaitand Promise.all().
Full implementation: