I am not well versed with promises and cannot find how to retrieve properties from it. I inherited the following code:
const [MessageData, setMessageData] = useState<any | null>(null);
const [snackbarData, setSnackbarData] = useState<any | null>(null);
PCore.getFeedUtils().getFeeds(feedKey, 'pyDashboardFeed', className, [], [], thePConn, false)
.then(() => {
setMessageData({
messageList: thePConn.getValue("pulse.messages","") || {},
messageIDs: (thePConn.getValue("pulse.messageIDs","")as any) || [],
});
})
.catch(() => {
setSnackbarData({ show:true, message:"Error retrieving comments"});
});
I need to get the properties in messageList, but I'm not sure how to do that.
If i stringify messageData, I get the following:
{"messageList": {
"SOCIAL M-369": {
"pxUpdateDateTime":"2025-01-13T19:50:39.417Z",
"pxCreateDateTime":"2025-01-13T19:50:39.417Z",
"postedByUser":{
"name":"Paul Smith",
"ID":"psmith@email.com"
},
"pyMessage":"test comment 2",
"ID":"SOCIAL M-369"
},
"SOCIAL M-368":{
"pxUpdateDateTime":"2025-01-13T19:45:29.091Z",
"pxCreateDateTime":"2025-01-13T19:45:29.091Z",
"postedByUser":{
"name":"Paul Smith",
"ID":"psmith@email.com"
},
"pyMessage":"test comment",
"ID":"SOCIAL M-368"
}
},
"messageIDs":["SOCIAL M-369","SOCIAL M-368"]}
But I cannot determine how to display the list of properties within messageList. I tried
const messageDetail = MessageData.map(messageList => (
<li key={messageList.ID}>
<div>{messageList.pyMessage}</div>
</li>
))
but get the error 'Cannot read properties of null (reading 'map')'. Any ideas how to properly define the list?
The issue arises because MessageData
starts as null
, and when you try to use map directly on it, it throws an error. (Since map
is a method on Array
.)
There are different approaches you could take, but I would personally do something like this:
const [MessageData, setMessageData] = useState<any | null>(null);
const messageDetail = MessageData?.messageIDs?.map(messageId=> (
<li key={messageId}>
<div>{MessageData?.messageList?.[messageId]?.pyMessage}</div>
</li>
))
Using Optional chaining (?.) ensures the code doesn't break when it can't access a property. Docs
This way you are mapping over the array messageIDs
that only contains the ids, then you use the messageID
as an index to get the full data that's stored in messageList
.
You are storing 2 properties in MessageData
, messageList
and messageIDs
. Since messageList
is an Object
instead of an Array
you have to transform it before you can map
over it. (Using Object.values
)
const messageDetail = MessageData?.messageList
? Object.values(MessageData.messageList).map(message => (
<li key={message.ID}>
<div>{message.pyMessage}</div>
</li>
))
: null; // Handle the case where MessageData or messageList is null
the convention for useState
, and most variable names in general, in JS/TS is to use camelCase. So MessageData
would be messageData
.
Whenever you see something that starts with a capital letter, you can in most cases assume it's either a Class or a Type/Interface if conventions were followed.