0

I am a newbie to ReactJS and was trying to fetch the data from JSON file. I have created 2 files one is products.json and app.jsx. I can get the result in console.log()

[{…}]
0
:
{title: "Product Title", img: "./p-1.jpg", des: "DES1", rs: 599}
length
:
1
__proto__
:
Array(0)

but it's rendering in view. I sometimes get undefined, or the data itself is not populating.

here's my react code.

import React from 'react';
import Request from 'superagent';
import ReactDOM from 'react-dom';

import {
    Container,
    Col,
    Row,
    Card
} from 'react-bootstrap';

class App extends React.Component {
    render() {
        return (
            <div className="container">
                <Header />
                <Content />
                <Footer />
            </div>
        );
    }
}

// Header starts 
class Header extends React.Component {
    componentDidMount() {
        //alert('Header');
    }
    render() {
        return (
            <header>
                <h1>Header !! </h1>
            </header>

        );
    }
}
// Header ends 

// Content starts 
class Content extends React.Component {
    constructor() {
        super();
        this.state = {
            data: []
        }
    }

    componentDidMount() {
        var url = "./products.json";
        Request.get(url)
            .then((res) => {
                console.log(res.body.data);
                console.log(res.body.data.title);
                //this.setState({data: data.conversations});
                this.setState({
                    PTitle: res.body.title,
                    PImg: res.body.img,
                    PDesc: res.body.des,
                    PRs: res.body.rs
                });
            })
            .catch(function (err) {
                alert(err);
                // err.message, err.response
            });

    }
    render() {
        return (
            <ul>
                {
                    this.state.data.map((key, i) => 
                    <ProductList key={i} products={key} />)
                }
            </ul>
        )
    }
}
// Content ends 

// Footer starts 
class Footer extends React.Component {
    render() {
        return (
            <div>
                Footer !!
            </div>
        )
    }
}
// Footer ends


// Products Starts
class ProductList extends React.Component {
    render() {
        return (
            2. - <li>{PTitle}</li>
        )
    }
}
// Products Ends

export default App;
8
  • I don't see you updating this.state.data anywhere? Am I missing it? Commented Jan 18, 2018 at 5:08
  • nope., where i have to update ? Commented Jan 18, 2018 at 5:08
  • Aha -- I just noticed you have that line commented out: this.setState({data: data.conversations});. Is that intentional? Commented Jan 18, 2018 at 5:09
  • by commenting that it throws error "data is not defined " Commented Jan 18, 2018 at 5:10
  • Ah, sorry -- you probably want to update it to res.body.data.conversations. Commented Jan 18, 2018 at 5:13

4 Answers 4

1

I am not familiar with superagent but It look like your input ./products.json that serve as http://localhost:3000/products.json (assume you run react at port 3000)

I think first step you can replace serve static json to use mock server like https://www.mocky.io/ and generate response

but If you can serve static json with superagent you have to receive your data and then set to your component state.

If your request is success, set state,

// componentDidMount()

let url = 'http://www.mocky.io/v2/5a6032db100000fa02307802';

Request.get(url)
  .then((res) => {
    this.setState({data: res.body.data});  
  }).catch(() => {});

and update your render() method

return (
  <ul>
    {
      this.state.data.map((product, index) => (
        <ProductList key={index} product={product} />
      ))
    }
  </ul>
)

and the last, your ProductList in render() method because you send product as a props

render() {
  const { title, img, des, rd } = this.props.product;

  return (
    <li>{title} : {des} : {rd} : {img}</li>
  )
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks a lot.. my missing part was setting const variables while printing.
{ "data": [ { "id": 1, "title": "Jackets", "img": "./img/p1.jpg", "rs": 9000, "buy": "Add to Cart", "details": "View Details", "detailPage": [ { "productDetail": "Made of Pure Leather", "qty": 4, "size" : 36 } ] } } i how do i call detailPage [] and objects in render ?
If your this.state.data is your response above, then you can call detailPage (Array) with map() like your this.state.data.map() : detailPage.map(data => <p>{data.productDetail}</p>)
componentWillMount() { let url = "./products.json"; Request.get(url) .then((res) => { this.setState({ data: res.body.data }); }) .catch(function (err) { alert(err); }); } render() { return ( <Container> <ul> { this.data.detailPage.map(data => <p>{data.productDetail}</p>) } </ul> </Container> ) }
Printing This gives me a error > Uncaught TypeError: Cannot read property 'detailPage' of undefined
|
1

It looks like superagent uses text rather than body as one might expect. So what you'll need to do is parse your json file like this:

Request.get(url).then((res: any) =>{
    const json = JSON.parse(res.text);
    // If you have a conversations item in that response you can then do this
    this.setState({data: json.conversations});
    ...

Assuming that the value of conversations is an Array, you will have no problem then using this.state.data.map to iterate/loop over the values.

Comments

0

Edited: What you need is

this.setState({data: res.body.data});

Then

this.state.data.map((one_product,i) => (
   <Product key={i} product={one_product}/>
);

and

class Product extends React.Component {
    render() {
        return (
            <li>{this.props.product.title}</li>
        );
    }
}

4 Comments

does your Request return an array of info for multiple products?
yes. [{…}] 0 : {title: "Product Title", img: "./p-1.jpg", des: "DES1", rs: 599} length : 1 proto : Array(0)
Edited, try it out
if its a nested how do i do it ? { "data": [ { "id": 1, "detailPage": [ { "productDetail": "Made of Pure Leather" } } ]
0

Do setState for data array after the res in Ajax call. You are already doing that but commented. Try the below it has slight change

this.setState({
    data: res.body (or) res.body.data
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.