I use lodash
map function in a react app in order to handle an array of objects that is returned as a response from a server. That works well when the response is indeed an array of objects. Sometimes though the response is just a single object. In that case, my code does not work.
render(){
const { data } = this.state;
const simplifiedData = data && _.get(data, ['Soap:Envelope', 'Soap:Body', 'ReadMultiple_Result', 'ReadMultiple_Result', 'ItemCharacteristics']);
const beautifiedData = _.map(simplifiedData, simple => _.reduce(simple, (r, value, key) => ({
...r,
[key]: value['_text']
}), {}));
return (
<div>
{
beautifiedData.map((product, i) => {
return (
<ItemDetailsCard
key={i}
itemNo={product.Item_No}
code={product.Code}
Description_2={product.Description_2}
GrossRequirement={product.GrossRequirement}
ScheduledRcpt={product.ScheduledRcpt}
ExpectedDate={product.ExpectedRcptDate}
Inventory={product.Inventory}
ProjAvailBalance={product.ProjAvailBalance}
/>
);
})
}
Here is an example of single object response:
{
"Soap:Envelope":{
"_attributes":{
"xmlns:Soap":"http://schemas.xmlsoap.org/soap/envelope/"
},
"Soap:Body":{
"ReadMultiple_Result":{
"_attributes":{
"xmlns":"urn:microsoft-dynamics-schemas/page/itemcharacteristics"
},
"ReadMultiple_Result":{
"ItemCharacteristics":{
"Key":{
"_text":"44;GRUAAAJ7/zAAMQAtADAAMAAxADUAAAACewMwADUAMQ==9;4258681930;"
},
"Item_No":{
"_text":"01-0015"
},
"Code":{
"_text":"051"
},
"Description_2":{
"_text":"ΜΑΥΡΟ"
},
"GrossRequirement":{
"_text":"0"
},
"ScheduledRcpt":{
"_text":"0"
},
"ExpectedRcptDate":{
"_text":"0001-01-01"
},
"Inventory":{
"_text":"0"
},
"ProjAvailBalance":{
"_text":"0"
}
}
}
}
}
}
}
and an example of an array of objects response:
{
"Soap:Envelope":{
"_attributes":{
"xmlns:Soap":"http://schemas.xmlsoap.org/soap/envelope/"
},
"Soap:Body":{
"ReadMultiple_Result":{
"_attributes":{
"xmlns":"urn:microsoft-dynamics-schemas/page/itemcharacteristics"
},
"ReadMultiple_Result":{
"ItemCharacteristics":[
{
"Key":{
"_text":"44;GRUAAAJ7/zAAMQAtADAAMAAwADgAAAACewMxADcAMg==9;4258681780;"
},
"Item_No":{
"_text":"01-0008"
},
"Code":{
"_text":"172"
},
"Description_2":{
"_text":"ΜΠΛΕ"
},
"GrossRequirement":{
"_text":"0"
},
"ScheduledRcpt":{
"_text":"0"
},
"ExpectedRcptDate":{
"_text":"0001-01-01"
},
"Inventory":{
"_text":"41.1"
},
"ProjAvailBalance":{
"_text":"41.1"
}
},
{
"Key":{
"_text":"44;GRUAAAJ7/zAAMQAtADAAMAAwADgAAAACewM2ADIAOA==9;4258681790;"
},
"Item_No":{
"_text":"01-0008"
},
"Code":{
"_text":"628"
},
"Description_2":{
"_text":"ΧΡΥΣΟ"
},
"GrossRequirement":{
"_text":"0"
},
"ScheduledRcpt":{
"_text":"0"
},
"ExpectedRcptDate":{
"_text":"0001-01-01"
},
"Inventory":{
"_text":"40.2"
},
"ProjAvailBalance":{
"_text":"40.2"
}
},
{
"Key":{
"_text":"44;GRUAAAJ7/zAAMQAtADAAMAAwADgAAAACewM3ADAAMw==9;4258681800;"
},
"Item_No":{
"_text":"01-0008"
},
"Code":{
"_text":"703"
},
"Description_2":{
"_text":"ΓΚΡΕΝΑ"
},
"GrossRequirement":{
"_text":"0"
},
"ScheduledRcpt":{
"_text":"0"
},
"ExpectedRcptDate":{
"_text":"0001-01-01"
},
"Inventory":{
"_text":"34.1"
},
"ProjAvailBalance":{
"_text":"34.1"
}
}
]
}
}
}
}
}
Could someone provide the logic of handling a response that is a single object?
It seems like you are using lodash
in your code, since I see you use underscore expression. In that case, try to use _.castArray
on your state data to ensure you always use array in rendering:
const beautifiedData = _.map(_.castArray(simplifiedData), simple => _.reduce(simple, (r, value, key) => ({
...r,
[key]: value['_text']
}), {}));
Better yet, you can check and preprocess your server response before updating state to ensure state.data
only store array, regardless of number of items in response.