I have a program which is able to retrieve the data from the an API I have created, using the following component which interacts with the backend:
import React, { Fragment, useEffect, useState } from 'react'
import { Button, Stack } from '@mui/material';
import TabsComponent from './TabsComponent';
import axios from 'axios';
import { getIssues } from '../../API';
import IssueApiData from '../../../../backend/types/issue.type.d'
import IssueInterface from '../../../../backend/types/IssueInterface'
type Props = {}
// TODO: create context for current rendered component?
// TODO: Add to API.ts file the axios requests to clean component
function Issues({ }: Props) {
const [issuesList, setIssuesList] = useState<IssueInterface[]>([]); // we retrieve from DB issues - we need it to look the same object's structure
const [hasLoaded, setHasLoaded] = useState(false);
useEffect(() => {
setHasLoaded((prev) => false)
try {
axios({
method: 'get',
url: 'http://localhost:8001/api/issues',
headers: { 'Content-type': "application/json" }
}).then((response) => {
setIssuesList((prev: any[]) => response.data.issues.map((issue: IssueInterface) =>
prev.push(issue)))
console.log(issuesList)
setHasLoaded((prev) => true)
})
} catch (err) {
console.log("error : " err);
}
}, [])
return (
<Fragment>
<>{console.log(issuesList)}</>
<Stack>
<h1>hi</h1>
{hasLoaded ? issuesList.map((issue: IssueInterface) => <div><h1>company: {issue.company_name}</h1></div>) : <></>}
</Stack>
</Fragment>
)
}
export default Issues
which causes my rendered page to look like:
which is not what i'm expecting to render (as I wish the company_name property to be printed as well).
now, the weird thing is that I am receiving in the beginning the correct data printed in line 25, and then it changes the value as can be seen in line 36 (console.log within the rendering function):
The backend:
router.route("/api/issues").get(getAllIssues);
export const getAllIssues = async (
req: Request,
res: Response
): Promise<void> => {
try {
const issues: IssueInterface[] = await Issue.find({});
res.status(200).json({ issues });
} catch (err) {
throw err;
}
};
I have no idea why would such thing can occur.. thanks for any attempt to help..
CodePudding user response:
you can see that at first the issues length is 0
, so when you try to access to element through mapping you get undefined which is normal.
Instead you can put a check before accessing to the element by adding ?
to .
so it becomes ?.
hasLoaded ? issuesList?.map((issue: IssueInterface) => <div><h1>company: {issue?.company_name}</h1></div>) : <></>}
CodePudding user response:
setIssuesList((prev: any[]) => response.data.issues.map((issue: IssueInterface) => prev.push(issue)))
console.log(issuesList)
you should know in line 25, your console.log print prev value of the list, state value change after form render in next time, move console.log to behind of useEffect to see that