I have looked into other questions such as :
this.setState is not updating the state property
this.setState not updating state
I appreciate that setState is asynchronous.
This is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class AssignmentTracker extends React.Component {
constructor() {
super()
this.state= {
assignmentsJSON : [ ],
headerImg: "https://poster.keepcalmandposters.com/8738135.jpg"
}
}
componentDidMount() {
fetch('https://beehiveapi.lionhearttrust.org.uk/v3.5/planner/test/assignments?pageIndex=0&pageSize=20')
.then(response => response.json())
.then(response => {
const {assignments} = response.items
this.setState({
assignmentsJSON: assignments,
}, () => {
console.log(this.state.assignmentsJSON);
})
})
}
render() {
if (this.state.assignmentsJSON) {
var assignmentListItems = this.state.assignmentsJSON.map((data)=> <li key={data.id}>{data.title}</li>);
console.log(this.state.assignmentsJSON)
}
return (
<div className="row">
<header>
<img className="center-block img-responsive w-25" src={this.state.headerImg} alt="Keep Calm and Do Your Assignment" />
<h1 className="text-center">Homework Assignment Tracker</h1>
</header>
<div className="col-md-6 assignment-items">
<ul>
{assignmentListItems}
</ul>
</div>
<div className="col-md-6">
<h1> TESTIN'PLACEHOLDER </h1>
</div>
</div>
)
}
}
ReactDOM.render(
<AssignmentTracker/>,
document.getElementById('root')
);
/* Developer Notes Taken Whilst this app was being made
1- Use of CSS Input Checked in order to show assignments when clicked
2- Need to determine if radio buttons or check boxes are best for 1
3- Dev thinks a good sense of humour is good for teamwork and even better in a education environment
4- Due to 3, an image has been selected appropiately
5- Initialise state to have data called assignmentsJSON, an array that can take in JSON data via fetch GET request done in React lifecycle method
componentDidMount()
6- Re-factor img src of image selected in 3 to make use of initialising state, data called headerImg
7- Radio buttons for 2 would be better - if it were to look like an email UI then one at a time only
8 - Given URL endpoints not working unfortunately, have emaled Graham
9 - Using a meme api instead in the mean time
10- Use .map to loop through and display assignmentJSON prop in state after the array has been filled due to fetch in lifecycle hook
11- Hence, display each list item by 10's .map loop
*/
Please note I used basic npx create-react-app so the html is the basic boilerplate with a div with id app etc. I can show that too if needed but nothing has been changed from the boilerplate.
Issues:
After a fetch request is made in componentDidMount, the initial state prop assignmentsJSON, should get all the JSON data from the endpoint given in the fetch.
However, all console.logs simply state that this.state.assignmentsJSON is either only [ ] or undefined.
Even if I wait a long time, the initial state never gets updated.
I have also tried a different URL endpoint for the fetch e.g. https://api.imgflip.com/get_memes but same issue persists
The other initial state, headerImg, works completely fine.
Any insight would be greatly appreciated, I am a fellow patient Developer so please give guidance and I will take heed.
I have tried as shown above specifcally,
this.setState({
assignmentsJSON: assignments,
}, () => {
console.log(this.state.assignmentsJSON);
})
but unfortunately, the console logs merely undefined.
This then causes issues further on when .map is used and .map would not work on undefined etc.
Many thanks in advance anyone who can help.
Your issue is here:
const {assignments} = response.items
Change it to: const {items] = response;
You are trying to deconstruct an attribute from an object that does not exist. Those little curly braces mean 'Hey, give me assignments from inside of response.items`. Your response does not have an attribute named assignments. Only items and paging. The JSON returns the following object: {items: Array[20], paging: Object}.
You can log to the console and inspect your object like this.
const { items } = response;
console.log(response);
This will come in handy when you are trying to look at the paging object in your response.