I'm trying to use the github api to get a user's projects and list them in a popup window. I'm having trouble figuring out why async / await isn't working and the data i end up passing is always undefined.
This is how i fetch the data from the api (edited to use for... of):
export default async function GitHubFetch({ userName }) {
let returnArray = [];
let response = await customFetch(
Urls.GitHub + "users/" + userName + "/repos"
);
for (const element of response) {
let project = {};
project.name = element.name;
project.description = element.description;
project.html_url = element.html_url;
let langResponse = await customFetch(element.languages_url);
project.languages = Object.keys(langResponse);
returnArray.push(project);
}
console.log("the array i'm returning from fetch is: ", returnArray);
return returnArray;
}
the console.log of returnArray from this function is:
[{"name":"cthulu_finance","description":"stock-trading application written in react and node.js / express","html_url":"https://github.com/contip/cthulu_finance","languages":["TypeScript","HTML","CSS"]},{"name":"c_structures","description":"collection of data structures in c","html_url":"https://github.com/contip/c_structures","languages":["C"]},{"name":"masm_io_procedures","description":"Low-level implementations of string-to-int and int-to-string in x86 assembly","html_url":"https://github.com/contip/masm_io_procedures","languages":["Assembly"]}]
the array of projects from the above function is used to generate the list of projects by this:
export default function GitHubListDisplay({ projects }) {
let listItems = [];
console.log(projects);
if (Array.isArray(projects)) {
projects.forEach((project, index) => {
listItems.push(
<>
<ListGroup.Item action href={project.html_url}>
{project.name}
</ListGroup.Item>
<ListGroup.Item>{project.description}</ListGroup.Item>
<ListGroup horizontal>{HorizontalList(project.languages)}</ListGroup>
</>
);
});
}
return <ListGroup>{listItems}</ListGroup>;
}
and finally, it's all controlled by this function:
export default function GitHubPopUp({ userName }) {
const [projectData, setProjectData] = useState([]);
useEffect(() => {
async function fetchData() {
setProjectData(await GitHubFetch({ userName }));
console.log("the project data i fetched is: ", projectData);
}
fetchData();
}, []);
return (
<>
<OverlayTrigger
placement="right"
delay={{ show: 250, hide: 5000 }}
overlay={
<Popover>
<Popover.Title as="h3">{`GitHub Projects`}</Popover.Title>
<Popover.Content>
<strong>{userName}'s GitHub Projects:</strong>
{projectData.length > 0 && (
<GitHubListDisplay {...projectData} />
)}
</Popover.Content>
</Popover>
}
>
<Button variant="link">{userName}</Button>
</OverlayTrigger>
</>
);
}
From the main controller function, the state eventually gets set correctly, but if i console.log the projectData state directly after awaiting the Fetch function result, it's undefined.. result is:
the project data i fetched is: []
Additionally, even though i have
{projectData.length > 0 &&
before rendering the GitHubListDisplay component, console.logging the input projects
property always results in undefined. The function never ends up displaying anything.
Can anyone please help? I've spent an embarrassing number of hours trying to figure this out.