When mapping the results of a promise to a array variable, the map awaits the promise, but the array variable is returned as an unresolved promise before the value mapping occurs.
Code with calling api with axios.get() and mapping results to a variable:
const refreshTableData = async () => {
const clientState = getAccessTokenAndUrl();
let rowDataArray = [];
try {
let healthStatusResults = await axios.get(
{
baseUrl: clientState.apiUrl,
url: 'some/api/url/path',
responseType: 'json',
headers: {
'Content-Type': 'application/json',
'Authorization': ('Bearer ' + clientState.jssAccessToken)
},
params: {
isValid: false,
systemName: 'some_system_name'
}
// potentially add validate status to communicate 400 and 500 level errors
}
);
healthStatusResults.devices.map(
(device) =>{
console.log('device: ', device);
rowDataArray.push([
device.deviceId,
device.isValid
]);
});
} catch (error) {
// potentially add error message react component here
const errorMessage = 'Error - healthStatus api response error: ' + error;
console.log(errorMessage);
// alert(errorMessage);
}
console.log('refreshTableData - rowDataArray: ', rowDataArray);
return (rowDataArray);
}
Function using the result returned from refreshTableData:
const generateRows = (rowDataArray) => {
console.log('DevicesStatusTable - rowDataArray: ', rowDataArray);
let rows = [];
for (let i = 0; i < rowDataArray.length; i += 1) {
let columnDataArray = [rowDataArray[i][0], rowDataArray[i][1]];
rows.push(<DeviceStatusRow columnDataArray={columnDataArray} key={'statusRow-' + i} />);
};
return rows;
};
React component DeviceStatusTable calling generate rows:
export const DeviceStatusTable = (props) => {
return (
<div>
<table>
<DeviceStatusHeader systemName={props.systemName} />
<tbody>
{generateRows(props.rowDataArray)}
</tbody>
</table>
</div>
);
};
React component HealthDashboard calling DeviceStatusTable and passing in results of refreshTableData() as props:
export const HealthDashboard = () => {
return (
<div>
<DeviceStatusTable systemName="Minestar Edge" rowDataArray={refreshTableData()}/>
</div>
);
};
Notice the order and values of the console.log() statements:
tests/HealthDashboard/HealthDashboard.test.js
● Console
console.log
DevicesStatusTable - rowDataArray: Promise { <pending> }
at generateRows (js/DeviceStatusTable/DeviceStatusTable.jsx:19:13)
console.log
device: {
deviceId: 'device_1',
isValid: true,
systemName: 'minestar_edge',
timeDiscrepancy: 10
}
at map (js/HealthDashboard/HealthDashboard.jsx:39:25)
at Array.map (<anonymous>)
console.log
device: {
deviceId: 'device_2',
isValid: false,
systemName: 'minestar_edge',
timeDiscrepancy: 20
}
at map (js/HealthDashboard/HealthDashboard.jsx:39:25)
at Array.map (<anonymous>)
console.log
refreshTableData - rowDataArray: [ [ 'device_1', true ], [ 'device_2', false ] ]
at _callee$ (js/HealthDashboard/HealthDashboard.jsx:52:13)
I expected that the rowDataArray value wouldn't be returned to generateRows until it was resolved, but instead it gets passed back as a promise. Meanwhile the map process does await the promise resolution and the associated and subsequent logs return after the log from the generateRows function.
Why is rowDataArray being returned from refreshTableData before the healthStatusResults promise filling the rowDataArray is resolved?