2

I have a components that aims to display data from API:

class Item extends Component {
constructor(props) {
  super(props);
  this.state = {
    output: []
  }
}

componentDidMount() {
    fetch('http://localhost:3005/products/157963')
      .then(response => response.json())
      .then(data => this.setState({ output: data }));
  }


render() {
    console.log(this.state.output);
  return (
    <ItemPanel>
    <ItemBox>
    <BoxTitle>{this.state.output}</BoxTitle>
  </ItemPanel>
  );
  }
 export default Item;

console.log(this.state.output) returns proper data, while my component won't render, its throwing this error:

Objects are not valid as a React child (found: object with keys {id, general, brand, images}). If you meant to render a collection of children, use an array instead.

I guess the data from api is an object. I have tried using JSON.parse or toString() already :/

This is output from console: enter image description here

2
  • can you share what this.state.output it consoles? what exactly you want to show in <BoxTitle> from id, general, brand, images ? Commented Jun 10, 2019 at 8:38
  • Let;s try to show brand here, console.log is above Commented Jun 10, 2019 at 8:42

3 Answers 3

1

It seems like you are displaying whole object in <BoxTitle>, Let's try to show brand here. I have update the code given in question. Updated initial state output [] to {}

class Item extends Component {
constructor(props) {
  super(props);
  this.state = {
    output: {}
  }
}

componentDidMount() {
    fetch('http://localhost:3005/products/157963')
      .then(response => response.json())
      .then(data => this.setState({ output: data }));
  }


render() {
    console.log(this.state.output);
  const { brand = {name : ""} } = this.state.output // added default name until we get actual value
  return (
    <ItemPanel>
    <ItemBox>
    <BoxTitle>{brand.name}</BoxTitle>
  </ItemPanel>
  );
  }
 export default Item;
Sign up to request clarification or add additional context in comments.

4 Comments

Small fix was needed here: { brand = {name = ""} } -> { brand= {name: ""} }, and it is working now. Thanks a lot!
<ItemBox> is not closed should be <ItemBox/>
Im now struggling to access images from that api, have tried const { images = {primary:""} } = this.state.output; and a few variations, but still cant load image src. Help appreciated
try this, const { brand = {name : ""} , images: {primary: {...}} = this.state.output
0

While your component fetches from your API it renders the element tree described in the render function.

Initial state for output is an empty array and that's a good start.

You should consider what to display to your application user when loading data from the API or if the network request fails.

I'm quite sure that you don't want to render the object returned upon a successful API call as-is.

That said, JSON.stringify function can be used for viewing what result is set in state upon a successful API call before picking what fields will be displayed, how and where they are displayed.

Comments

0

you can better use conditional rendering,

render() {
    console.log(this.state.output);
  return (
    <ItemPanel>
     <ItemBox>
     {
       if(this.state.output.brand.name !=== null) ?
         <BoxTitle>{this.state.output.brand.name}</BoxTitle> :
       <BoxTitle>Brand Name is Empty</BoxTitle>
     }
    </ItemPanel>
  );
  }

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.