Been trying all morning and for the life of me I can't get individual array data to be displayed from my API. I am trying to display one body of text from an array at a time, and can only get it to output all at once. Had it working when the data was in JSON format but now its in an array I'm struggling to make it work.
My code:
componentDidMount() {
axios
.get(
"API_DATA"
)
.then((res) => {
let data = res.data
this.setState({ data, loading: false });
console.log(data)
});
}
render() {
if (this.state.loading) {
return <Loader />
}
// return table if loading is false
// handling error goes with the same logic
// table will only render if loading is false
else
return (
this.state.data.data).map((item) => (
<>
<p key={item.id}>{item.title}</p>
</>
))
}
}
I previously used added [0] or [1] etc to determine which element I wanted to display and this worked very nicely however if I try this.state.data.data[0]).map((item) => ( It states it is not a function.
Expected output of API:
{
"data": [
{
"id": 9,
"status": "published",
"body": "TEST1",
"availability": "internal",
"title": "Test1",
"posted_by": "Tester"
},
{
"id": 10,
"status": "published",
"body": "TEST",
"availability": "internal",
"title": "TEST2",
"posted_by": "Tester"
},
Related
I'm having trouble accessing the values of a nested array and I've been stuck on it for days, hoping someone can help!
I've just started learning React and i'm working on an app that fetches the data from Wordpress using graphql and apollo
The array structure when I console my data:
{__typename: 'Yarn', name: 'Brick Red', yarnFields: {…}}
name: "Brick Red"
yarnFields:
yarnColor: "#cb4154"
yarnFiber: Array(1)
0: {__typename: 'Fiber', name: 'Merino'}
length: 1
[[Prototype]]: Array(0)
yarnPrice: 6.5
__typename: "Yarn_Yarnfields"
[[Prototype]]: Object
__typename: "Yarn"
[[Prototype]]: Object
The array structure from graphql:
{
"data": {
"yarns": {
"nodes": [
{
"name": "Brick Red",
"id": "dGVybToyNTI=",
"yarnFields": {
"yarnColor": "#cb4154",
"yarnPrice": 6.5,
"yarnFiber": [
{
"name": "Merino"
}
]
}
},
{
"name": "Burgundy",
"id": "dGVybToyNzg=",
"yarnFields": {
"yarnColor": "#662d40",
"yarnPrice": 9.11,
"yarnFiber": null
}
},
{
"name": "Cobalt Blue",
"id": "dGVybToyOTQ=",
"yarnFields": {
"yarnColor": "#1664af",
"yarnPrice": 7.54,
"yarnFiber": null
}
},
etc
I can get all the other values by using this syntax:
{yarn?.yarnFields?.yarnPrice}
the value i need to get is yarnFiber.name ( in the case the value is "Merino")
but when i use the same syntax for yarnFiber it returns undefined
My JSX Code to map through the JSON object:
const { loading, error, data } = useQuery(YARNS_QUERY);
if (isEmpty ( data )){
return null;
}
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<>
{data.yarns.nodes.map((yarn, i) => (
<DK key={i} yarn={yarn}/>
))}
My Component where I display the yarn info:
return (
<div>
<div onClick={change}
data-color={yarn?.name}
data-price={yarn?.yarnFields?.yarnPrice}
data-fiber={yarn?.yarnFields?.yarnFiber?.name}
style={{
background:yarn?.yarnFields?.yarnColor,
width: '50px',
height: '50px',
// border:'5px dashed #2d2e2e',
borderRadius: '50%'}}>
fiber: {yarn.yarnFields?.yarnFiber?.name} // returns empty
</div>
</div>
);
I've tried mapping through the nested array but i can't seem to get the syntax correct to fit my code. i'm not even sure if thats what i need to do!
Any help appreciated but would love the solution in detail as I'm a total noob!
UPDATE:
the yarnFiber array has multiple values that need to be displayed
"name": "Burgundy",
"id": "dGVybToyNzg=",
"yarnFields": {
"yarnColor": "#662d40",
"yarnPrice": 9.11,
"yarnFiber": [
{
"name": "Merino Wool"
},
{
"name": "Silk"
},
{
"name": "Cashmere"
}
]
}
},
how should i reflect this in my code?
thanks again
yarnFiber is an array so you need to reference its objects by index:
fiber: {yarn.yarnFields?.yarnFiber && yarn.yarnFields?.yarnFiber.length > 0
? yarn.yarnFields?.yarnFiber[0].name
: 'No fiber'
}
If you need to display all names in the array you can just map through them:
{
yarn.yarnFields?.yarnFiber && yarn.yarnFields?.yarnFiber.length > 0
? yarn.yarnFields?.yarnFiber.map((fiber, index) => (
<div key={index}>{fiber.name}</div>
))
: 'No fibers';
}
I'm a beginner and trying to create a practice project. I'm trying to "patch" a data fetched from an API.
My json file looks like this:
{
"classes": [
{
"title": "Office Syndrome",
"length": "60 Minutes",
"instructor": "A. W.",
"difficulty": "Intermediate",
"description": "Suitable for people who are always constantly inactive working in front of computers.",
"availableSpot": "10",
"id": 1
},
{
"title": "Digestive Flow",
"length": "60 Minutes",
"instructor": "MJ",
"difficulty": "Beginners",
"description": "Good for digestion",
"availableSpot": "8",
"id": 2
}
]
I'm trying to create a functionality where the class is bookable where the availableSpot will be decreased by 1 after each booking.
My handleBook function currently looks like this:
const handleBook = (index) => {
setSelectedYogaClass(true);
if (selectedYogaClass === index) {
fetch("http://localhost:8000/classes", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ availableSpot: data.availableSpot - 1 }),
})
.then((res) => {
if (!res.ok) {
throw Error("Sorry, something went wrong");
}
})
.then((res) => {
console.log(res);
})
.catch((err) => {
setBookingError(err);
});
}
console.log(selectedYogaClass);
setModalIsOpen(false);
};
And this is how I am calling the function
<button
key={index}
onClick={() => handleBook(index)}
className="button button--outline"
>
Yes
</button>
However, I am getting a 404 error and am wondering what the problem is?
Could anyone point out what I am doing wrong?
Thank you so much in advance!
You need to specify specific resource when you use plural routes like http://localhost:8000/classes/:id.
If you want to update(PATCH) the availableSpot field of class with id 1, you should use http://localhost:8000/classes/1
An working example
I'm trying to access data further down into my JSON file. I am able to easily access data in the first two data sets in rows and area:
data.json
"rows": [
{
"uid":"001",
"type": "Lorem ipsum",
"area": [
{
"name": "London",
"number": "12345",
"wait": {
"start": {
"start_time": 1585129140,
"delay": 300
},
"end": {
"end_time": 1585130100,
"delay": 300
}
},
"in": 1585129140,
"out": 1585130100,
},
However when I try to access the data under wait which includes this block:
"wait": {
"start": {
"start_time": 1585129140,
"delay": 300
},
"end": {
"end_time": 1585130100,
"delay": 300
}
},
No data is getting returned on screen from my jsx file, but it is available in the console log
TimeTracker.jsx
const TimeTracker = (props) => {
const trainTime = useState(props.data);
console.log(props.data);
return (
<>
<div className={style.timeLabel}>
<div className={style.startTime}>{trainTime.start_time}</div>
<div className={style.endTime}></div>
</div>
</>
)
};
export default TimeTracker;
console.log
wait:
start:
start_time: 1585129140
delay: 300
__proto__: Object
end:
end_time: 1585130100
delay: 300
__proto__: Object
__proto__: Object
I've used the same pattern for passing props in other components and it works fine on the first two levels so I don't understand why it's not working. How do I get data from further in this JSON?
useState returns a tuple with the object and a function to set the value on the object. You probably need to change your component to something like this:
const TimeTracker = (props) => {
const [trainTime, setTrainTime] = useState(props.data);
console.log(props.data);
return (
<>
<div className={style.timeLabel}>
<div className={style.startTime}>{trainTime.start_time}</div>
<div className={style.endTime}></div>
</div>
</>
)
};
export default TimeTracker;
A nested property can not be accessed by one level of a.b so instead of
<div className={style.startTime}>{trainTime.start_time}</div>
it should be
<div className={style.startTime}>{trainTime.wait.start.start_time}</div>
I fetch an api on componentDIdMount() then store the json to a state then I pass that state as a prop, I have no problem showing the data except on arrays.
<Component details={this.state.details} />
json:
{
"adult": false,
"backdrop_path": "/qonBhlm0UjuKX2sH7e73pnG0454.jpg",
"belongs_to_collection": null,
"budget": 90000000,
"genres": [
{
"id": 28,
"name": "Action"
},
{
"id": 878,
"name": "Science Fiction"
},
{
"id": 35,
"name": "Comedy"
},
{
"id": 10751,
"name": "Family"
}
]
}
then I try to map the genres:
<div className={style.genre}>
{details.genres.map(g => (
<span key={g.id}>{g.name}</span>
))}
</div>
But then I get Cannot read property 'map' of undefined, I don't know why this is happening because I'm able to do details.budget
It's trying to read data before you get the result from api.
so write the map function as
{details&&details.genres&&details.genres.map(g => (
<span key={g.id}>{g.name}</span>
))}
In react Initially when component is mounted, render() function is called and then componenentDidMount() is called in which you fetch data. So Initially details is empty. So you need to write the condition.
I've defined an empty array in the react component constructor which I wish to assign with json response data from an API call
class Grid extends Component {
constructor(props) {
super(props);
this.state = {
blogs : []
};
}
I call the componentDidMount method to load data on this component where I'm using setState to assign values
componentDidMount(){
Axios.get("/api/blogs").then(response => {
const blogData = response.data;
this.setState({blogs: blogData.data});
});
}
The JSON response data is as follows (Laravel collection resource with meta and links)
{
"data": [
{
"title": "Experiments in DataOps",
"status": true,
"publish_date": "2020-01-29",
"slug": "experiments-in-dataops"
},
{
"title": "What is it about certifications anyway?",
"status": true,
"publish_date": "2020-01-29",
"slug": "what-is-it-about-certifications-anyway"
}
],
"links": {
"self": "link-value",
"first": "http://adminpanel.test/api/blogs?page=1",
"last": "http://adminpanel.test/api/blogs?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "http://adminpanel.test/api/blogs",
"per_page": 15,
"to": 2,
"total": 2
}
}
the blogs array however remains undefined when I'm calling it later in populating the grid data
<BootstrapTable data={this.blogs} version="4" striped hover pagination search options={this.options}>
I get an empty table, calling console.log on blogs and this.blogs reveals it's undefined.
I'm using reactstrap and react-bootstrap-table for this grid component.
You are not accessing the state correctly to access the blogs use this.state.blogs:
<BootstrapTable data={this.state.blogs} version="4" striped hover pagination search options={this.options}>