Creating a table in React from JSON inputed from Flask - javascript

I am trying to make a table in React from the response I've got from my flask app. The code I am using is below. Please could someone help me? I am unsure as to where to start and how to do it.
import React, { Component } from "react";
import { render } from "react-dom";
import axios from "axios";
class Data extends Component {
constructor() {
super();
this.state = {
products: ""
};
}
componentDidMount() {
this.getDataAxios();
}
async getDataAxios() {
const response = await axios.get("http://141.123.1:5000/product");
this.setState({ products: response.data });
}
render() {
return (
<div>
<h1>response data</h1>
</div>
);
}
}
export default Data;
and the input from the local server is:
"products": [
{
"action": "update",
"id": 2,
"object_identifier": 20,
"object_type": "meal",
"s3_location": "location-110"
},
{
"action": "update",
"id": 3,
"object_identifier": 20,
"object_type": "meal",
"s3_location": "location-120"
},
{
"action": "update",
"id": 4,
"object_identifier": 60,
"object_type": "meal",
"s3_location": "location-1120"
},
{
"action": "update",
"id": 5,
"object_identifier": 70,
"object_type": "meal",
"s3_location": "location-1323120"
}
]
as an extra and rather cheeky question, I am unsure right now how to get my flask rest api to work without using Moesif CORS. Does anyone know a way?
Thank you so much for the help as always.
//A

Map the data if it exists
render() {
return (
<div>
<h1>response data</h1>
{this.state.products && this.state.products.length > 0 && this.state.products.map(product => <Product {...product} />)}
</div>
);
}
}
Make a Product component that renders 1 product and put it in here. Then fill it with data you get from each iteration of the array.

Related

setting state within nested response

I am building a react app and I am setting the state with api of nested response of nested state But the state is not setting the way I want.
response that is receiving from api
[
{
"id": 70,
"title": "feefifef",
"images": [
{
"id": 28,
"text": "First Image"
"blog_id": 70,
},
{
"id": 28,
"text": "First Image",
"blog_id": 70,
}
]
}
]
App.js
class App extends React.Component {
constructor(props){
super(props)
this.state = {
blogs = [
{
id: 0,
title: "",
images: [
{
id:0,
text:""
}
]
}
]
}
}
componentDidMount() {
let data;
axios.get('http://127.0.0.1:8000/api/blogs/').then((res) => {
data = res.data;
this.setState({
blogs: data.map((blog) => {
return Object.assign({}, blog, {
id: blog.id,
title: blog.title,
images: blog.images,
}
})
})
})
}
render() {
const blogs = this.state.blogs.map((blog) => (
<BlogList
id={blog.id}
title={blog.title}
images={blog.images}
/>
))
}
return (
<div>{blogs}</div>
)
}
class BlogList extends React.Component {
constructor(props){
super(props)
}
return (
<div>
Title: {this.props.title}
Images: {this.props.images}
</div>
)
}
What is the problem ?
Images are not showing after Title. I am trying to show all images in BlogList class of every blog.
I have also tried using (in BlogList class)
this.props.images.map((img) => {
return (
<div>
Title: {this.props.title}
Images: {img.text}
</div>
)
}
But it showed me
this.props.images.map is not a function.
then I think the problem is with setting state of images (I may be wrong).
When I tried to print this.props.images then it is showing
0: {id: 28, text: '1111', blog_id: 71}
length: 1
[[Prototype]]: Array(0)
I am new in react, Any help would be much Appreciated. Thank You in Advance
this.props.images is an array and hence you can't use {this.props.images} directly. Other wise you will get an error like this "Objects are not valid as a React child. If you meant to render a collection of children, use an array instead"
You have to use something like this
render() {
return (
<div>
Title: {this.props.title} <br/>
Images:
{this.props.images?.map((image, i) => (
<div key={image.id}>
{image.id}<br/>
{image.text}<br/>
{image.blog_id} <br/>
</div>
))}
</div>
);
}

Error: Objects are not valid as a React child. If you meant to render a collection of children, use an array instead. Getting data from JSON

guys! I'm using ReactJS to create a small website. Since I added the following code it starts showing an error: Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
Code:
import { useState, useEffect } from 'react';
import { motion, useAnimation } from 'framer-motion';
import './css/App.min.css';
import config from './config';
function App() {
return (
<div className="myskills">
<Skills skillType="coding" />
</div>
);
}
function Skills(props){
const skillType = props.skillType;
const result = config.skills.filter(skill => skill.cat == skillType);
console.log(result);
result.map((skill, index) => (
<div className="singleSkill" key={index}>
{skill.name} Level: {skill.level}
</div>
));
return (<div>{result}</div>);
}
config.json
{
"skills": [
{
"name": "HTML",
"level": 5,
"cat": "coding"
},
{
"name": "CSS",
"level": 5,
"cat": "coding"
},
{
"name": "PHP",
"level": 4,
"cat": "coding"
}
]
}
Any ideas what's the problem?
The return statement in your Skills component is basically just this:
return (config.skills.filter(skill => skill.cat == skillType));
hence the "Objects are not valid as a React child" error.
Since result.map doesn't modify the original array, a better solution might look something like this:
function Skills(props) {
const skillType = props.skillType;
const result = config.skills.filter(skill => skill.cat == skillType);
return (
<div>
{result.map((skill, index) => (
<div className="singleSkill" key={index}>
{skill.name} Level: {skill.level}
</div>
))}
</div>
);
}

Render array of objects React

My local JSON file is as follows
[
{ "time": "2017", "Id": 1, "value": 40 },
{ "time": "2018", "Id": 1, "value": 65 },
{ "time": "1018", "Id": 1, "value": 34 }
]
I imported the JSON like:
import * as readings from '../data/readings';
And I want to render my data in a list in a React component.
This is what I have been tried:
import * as readings from '../data/readings';
class Table extends Component {
render (){
const data = Object.keys(readings).map((row, index) =>
<li key={index}> {row} </li>);
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;
After rendering this component, I will see "default" on the screen but my aim is to have each object in one row like:
"time": "2017", "Id": 1, "value": 40
"time": "2018", "Id": 1, "value": 65
"time": "1018", "Id": 1, "value": 34
Can someone tell me what I am doing wrong?
I've read a lot of related question but I could not relate.
Edit:
My data is an array itself but the import gives it like an object. That's why I use Object.keys and not readings.map
readings is itself an array so that is what you want to map over: readings.map(). The items in it are the objects you want to display, so there is where you want to use Object.keys(). Since you want to use the values as well, Object.entries() is slightly more readable.
Also, you are importing data from a JSON file so you should import the data as though it was a default export. You should explicitly specify the .json file type since it is not a .js file.
import readings from '../data/readings.json';
class Table extends Component {
render() {
const data = readings.map((reading, index) => {
const readingData = Object.entries(reading).map((k, v) => <span>{k}: {v}</span>);
return <li>{readingData}</li>;
};
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;
Your readings is not an object, it's an array! So, what you should do is to iterate over it, and for every inside object, do the process of Object.keys(readings).map()
import * as readings from '../data/readings';
class Table extends Component {
render (){
const data = readings.map((row, index) =>
<li key={index}>
{
Object.keys(row).map(e =>
`${e[0]: e[1],} `
}
)
</li>
)
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;
Your readings data is already an Array. You can directly use map on it.
import * as readings from '../data/readings';
class Table extends Component {
render (){
const readingsArray = Object.keys(readings).map(key => readings[key]);
const data= readingsArray.map(obj => <li>{JSON.stringify(obj)}</li>);
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;

TypeError: variable is undefined despite being able to log the variable correctly

I'm trying to get a simple list of lessons contained in a course from an endpoint.
If I try console.log(this.state.course.lessons) an array contained 3 items is displayed.
However,if I try console.log(this.state.course.lessons.map(//function) I keep getting
TypeError: this.state.course.lessons is undefined
How can I map a function to the lessons array so I can render them as a list.
component
import React, { Component } from 'react'
export class CourseDetail extends Component {
constructor(props) {
super(props);
this.state = {
course: []
};
}
componentDidMount() {
fetch(`http://127.0.0.1:8000/api/courses/${this.props.match.params.id}`)
.then(res => res.json())
.then((course) => {
this.setState({
course: course,
});
console.log(this.state.course.lessons)
});
}
render() {
return (
<div>
{this.state.course.lessons.map((lesson)=>(console.log(lesson)))}
<h1>{this.state.course.title}</h1>
</div>
)
}
}
export default CourseDetail
json returned from end point
{
"id": 1,
"lessons": [
1,
2,
3
],
"owner": 1,
"rating": 0,
"title": "Course 1",
"description": "course 1 desc",
"pub_date": "2019-11-23",
"is_live": false,
"category": 1
}
Most obvious solution would be just to give the object a default state if you want to access it:
constructor(props) {
super(props);
this.state = {
course: {
lessons: []
}
};
}
The problem on your code is the life cycles (Mount-> Render-> DidMount), and in this render, u have not fetch the data yet.
You can try this:
render() {
if (!this.state.course.lessons) return null //this line
return (
<div>
{this.state.course.lessons.map((lesson)=>(console.log(lesson)))}
<h1>{this.state.course.title}</h1>
</div>
)
}

Unable to display API call result to WebPage

I have react App.js page from where i am calling Django Rest API and i am getting response as an array now this array i have nested components and i want that nested component to be listed in my code.
If i can showcase single record given by single person name when i try to do with more than one i am getting following error.
Warning: Each child in an array or iterator should have a unique "key" prop.
Now if i change API URL as below
https://e2isaop.rokuapp.com/api/perns/1
I can able to view data in HTML but when it comes to all persons it fails.
I am sorry i am new react not sure how to iterate over sub array of result.
Kindly guide me here for best practice for this.
Here is API Response in JSON
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uri": "/api/Persons/1",
"PersonId": 1,
"PersonName": "Nirav Joshi",
"Person_Image": "https://ja.amazonaws.com/media/persons/None/51e1257926f3cb184089c41fa54b8f8e1b65a98f1e35d39e55f2b6b335e83cf4.jpg",
"Person_sex": "M",
"Person_BDate": "2019-04-19",
"Person_CDate": "2019-04-23"
},
{
"uri": "/api/Persons/2",
"PersonId": 2,
"PersonName": "New Joshi",
"Person_Image": "https://ja.amazonaws.com/media/persons/None/cc08baaad2ccc918bc87e14cac01032bade23a0733b4e313088d61ee78d77d64.jpg",
"Person_sex": "F",
"Person_BDate": "2011-11-21",
"Person_CDate": "2019-04-27"
},
]
}
Here is react App.js code.
import React from "react";
import ReactDOM from "react-dom";
import Persons from "./Persons";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
persons: []
};
}
componentDidMount() {
fetch("https://e2isen.okuapp.com/api/psons/")
.then(response => response.json())
.then(data => {
let apipersons;
if (data.isNull) {
apipersons = [];
} else {
apipersons = [data];
console.log(apipersons);
}
this.setState({ persons: apipersons });
});
}
render() {
return (
<div>
<h1>Welcome to PersonAPI</h1>
<div>
{this.state.persons.map(pers => {
return (
<Persons
PersonName={pers.PersonName}
key={pers.PersonId}
Person_Image={pers.Person_Image}
Person_BDate={pers.Person_BDate}
Person_sex={pers.Person_sex}
/>
);
})}
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
It should give me result for Four person with their details
PersonName
PersonImage
PersonBdate
PersonSex
You should do :
// apipersons = [data];
apipersons = data.results

Categories

Resources