so i am fetching data from an API on page load in reactJS
useEffect(() => {
fetch('https://xxxxx/getdata',{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({
Action : "xxxx",
OrganisationID : "xxx-1000",
})
})
.then((res) => res.json())
.then((json) => {
setResponse(json)
console.log(json)
})
.catch((err) => {
console.log(err.message);
});
}, []);
The json returns me an array of 2 objects.
{
"OrganisationJobPosts": [
{
"Languages": [
"English",
"Spanish"
],
"Project_Type": "One-Time Project",
"Description": "This job requires Java and Javascript developers",
"Status": "open",
"Proposal_Questions": [
"question1?",
"question2?"
],
"Entity": "JOBPOST",
"Organization_Name": "ABC Company",
"Jobpost_ID": "JOBPOST-20220608-10",
"Jobpost_Title": "Web Developer",
"Organization_ID": "ORGANIZATION-1000",
"Rates": "$20/hour",
"Experience": "< 3 Years",
"Created_Date": 20220608,
"Location": "Singapore",
"SK": "JOBPOST-20220608-10",
"PK": "ORGANIZATION-1000",
"Skill_Set": [
"HTML",
"Javascript"
]
},
{
"Languages": [
"English",
"French"
],
"Project_Type": "Ongoing Project",
"Description": "This job requires DB design skills",
"Status": "Closed",
"Proposal_Questions": [
"Question A?",
"Question B?"
],
"Entity": "JOBPOST",
"Organization_Name": "ABC Company",
"Jobpost_ID": "JOBPOST-20220608-11",
"Jobpost_Title": "Database Developer",
"Organization_ID": "ORGANIZATION-1000",
"Rates": "$20/hour",
"Experience": "< 3 Years",
"test": [
"test"
],
"Created_Date": 20220610,
"Location": "TBD",
"SK": "JOBPOST-20220608-11",
"PK": "ORGANIZATION-1000",
"Skill_Set": [
"DynaomDB",
"GraphDB"
]
}
]
}
I then tried looping through the said array
<header className="headerTabContent">
{(() => {
for (var key in response) {
if (response.hasOwnProperty(key)) {
const resultarray = response[key]
console.log(resultarray)
for (var i=0;i<=resultarray.length;i ) {
return(<h1 className="heading" onClick={()=>navigate('/dashboard/hire/discover/job-post')}>{resultarray[i].Jobpost_ID}</h1>)
}
}
}
})()};
</header>
As seen my array length is 2. But the loop always outputs only the first array object (Job ID JOBPOST-20220608-10) wheras the second array item (JOBPOST-20220608-11) is not output. I can confirm the size is correct because before the second for loop, I did a console log of the length and found 2 objects. Am I doing something wrong here ?
CodePudding user response:
Inside your for
you call return
(1):
This ends the arrow function in (2), returning the <h1>
.
What you want is to call .map
instead:
<header className="headerTabContent">
{(() => {
for (var key in response) {
if (response.hasOwnProperty(key)) {
const resultarray = response[key]
console.log(resultarray)
return resultarray.map(r => (
<h1 className="heading" onClick={()=>navigate('/dashboard/hire/discover/job-post')}>{r.Jobpost_ID}</h1>
));
}
}
})()}
</header>
Though that will only return the resultarray
of the first property of response
. To return all properties on all of response
's keys, you'll have to nest .map
calls (or .flatMap
/.map
) as shown below:
<header className="headerTabContent">
{Object.values(response).flatMap(resultarray => {
console.log(resultarray)
return resultarray.map(r => (
<h1 className="heading" onClick={()=>navigate('/dashboard/hire/discover/job-post')}>{r.Jobpost_ID}</h1>
));
})}
</header>
Demo below:
const jsonResponse = {
"OrganisationJobPosts": [
{
"Languages": [
"English",
"Spanish"
],
"Project_Type": "One-Time Project",
"Description": "This job requires Java and Javascript developers",
"Status": "open",
"Proposal_Questions": [
"question1?",
"question2?"
],
"Entity": "JOBPOST",
"Organization_Name": "ABC Company",
"Jobpost_ID": "JOBPOST-20220608-10",
"Jobpost_Title": "Web Developer",
"Organization_ID": "ORGANIZATION-1000",
"Rates": "$20/hour",
"Experience": "< 3 Years",
"Created_Date": 20220608,
"Location": "Singapore",
"SK": "JOBPOST-20220608-10",
"PK": "ORGANIZATION-1000",
"Skill_Set": [
"HTML",
"Javascript"
]
},
{
"Languages": [
"English",
"French"
],
"Project_Type": "Ongoing Project",
"Description": "This job requires DB design skills",
"Status": "Closed",
"Proposal_Questions": [
"Question A?",
"Question B?"
],
"Entity": "JOBPOST",
"Organization_Name": "ABC Company",
"Jobpost_ID": "JOBPOST-20220608-11",
"Jobpost_Title": "Database Developer",
"Organization_ID": "ORGANIZATION-1000",
"Rates": "$20/hour",
"Experience": "< 3 Years",
"test": [
"test"
],
"Created_Date": 20220610,
"Location": "TBD",
"SK": "JOBPOST-20220608-11",
"PK": "ORGANIZATION-1000",
"Skill_Set": [
"DynaomDB",
"GraphDB"
]
}
]
};
function App() {
const [response, setResponse] = React.useState({})
React.useEffect(() => {
// returning a promise isntead of calling fetch for demo purposes
Promise.resolve(jsonResponse)
.then((json) => {
setResponse(json)
console.log(json)
})
.catch((err) => {
console.log(err.message);
});
}, []);
return (
<header className="headerTabContent">
{(() => (
Object.values(response).flatMap(resultarray => {
console.log(resultarray)
return resultarray.map(r => (
<h1 className="heading" onClick={()=>navigate('/dashboard/hire/discover/job-post')}>{r.Jobpost_ID}</h1>
));
})
))()}
</header>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App />);
<script type="text/javascript" src="//unpkg.com/react@18/umd/react.production.min.js"></script>
<script type="text/javascript" src="//unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="app"></div>
CodePudding user response:
A slightly simpler way forward would be to have a small function that can map
over the OrganisationJobPosts
array and return all the ids which you can then, in turn, map
over to create the heading elements you need.
I imagine that you also need to include the id in the navigation link too as this example shows. Slightly different from your code the onClick
handler calls a separate function which extracts the id from the element's dataset, and then uses that in the string for the endpoint.
const { useState } = React;
function Example({ res }) {
function getJobIds(res) {
return res.OrganisationJobPosts.map(post => {
return post.Jobpost_ID;
});
}
function handleClick(e) {
const { id } = e.target.dataset;
const path = '/dashboard/hire/discover/job-post';
// navigate(`${path}/${id}`);
console.log(`${path}/${id}`);
}
return (
<section>
{getJobIds(res).map(id => {
return (
<h1
data-id={id}
className="heading"
onClick={handleClick}
>{id}
</h1>
);
})}
</section>
);
}
const res={OrganisationJobPosts:[{Languages:["English","Spanish"],Project_Type:"One-Time Project",Description:"This job requires Java and Javascript developers",Status:"open",Proposal_Questions:["question1?","question2?"],Entity:"JOBPOST",Organization_Name:"ABC Company",Jobpost_ID:"JOBPOST-20220608-10",Jobpost_Title:"Web Developer",Organization_ID:"ORGANIZATION-1000",Rates:"$20/hour",Experience:"< 3 Years",Created_Date:20220608,Location:"Singapore",SK:"JOBPOST-20220608-10",PK:"ORGANIZATION-1000",Skill_Set:["HTML","Javascript"]},{Languages:["English","French"],Project_Type:"Ongoing Project",Description:"This job requires DB design skills",Status:"Closed",Proposal_Questions:["Question A?","Question B?"],Entity:"JOBPOST",Organization_Name:"ABC Company",Jobpost_ID:"JOBPOST-20220608-11",Jobpost_Title:"Database Developer",Organization_ID:"ORGANIZATION-1000",Rates:"$20/hour",Experience:"< 3 Years",test:["test"],Created_Date:20220610,Location:"TBD",SK:"JOBPOST-20220608-11",PK:"ORGANIZATION-1000",Skill_Set:["DynaomDB","GraphDB"]}]};
ReactDOM.render(
<Example res={res} />,
document.getElementById('react')
);
.heading { font-size: 1em; color: black; }
.heading:hover { color: royalblue; cursor: pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>