2

I am working on my first experiment with React, trying to consume and display some data via an API that I also wrote (using the Django REST framework)

I am seeing the objects populate in the Console, but they don't render on the page. I am also seeing an error in the console:

Uncaught (in promise) TypeError: Cannot read property 'length' of undefined

Which refers to line #18 in my ChangeList component:

	import React from 'react';


	class ChangeList extends React.Component {
		constructor() {
	  	super();
	 		 this.state={items:[]};
	  }
	  componentDidMount(){
	  	fetch(`http://127.0.0.1:8000/backup/changes/1/Lead.json`)
	 		.then(result=>result.json())
			.then(items=>console.log(items) )
	    .then(items=>this.setState( {items} ))
	  }
	  render() {
	  	return(
	    	<ul>
	          {this.state.items.length ?
	          	this.state.items.map(item => <li> {item} </li>)
	            : <li>Loading...</li>
	          }
	      </ul>
	   )
	  }
	}

	export default ChangeList
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

So how do I restructure this React component so that this.state.items.length is evaluated after all of the items are loaded? Or am I still misunderstanding the issue, and if so, what am I doing wrong in rendering the data?

1 Answer 1

3

Your problem is the .then(items=>console.log(items)), since console.log() returns undefined.

When undefined is returned, this line .then(items=>this.setState( {items} )) sets the state as { items: undefined }, and this.state.items has no length property.

Just remove the console.log() statement or change it to:

.then(items=> { console.log(items); return items; })
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I removed the console.log() statement as you suggested but still nothing is rendered in the browser. Also, there is no output to the console. If I add back the console.log() statement with the changes that you suggested ( .then(items=> { console.log(items); return items; }) ) the objects are logged to the console, and there are no errors in the console (just the JSON Object) but still nothing renders in the UI.
What does a console.log(this.state) in render show?
I added console.log(this.state) to the render function (not sure if I did this correctly? gist.github.com/joefusaro/4e09d0949e80dcbb1a02e01405dbc360 ) and now I'm seeing the following: imgur.com/a/C0SgG
In log you can see that the data is in items.results. Make this change in your code .then(items=>this.setState( {items} )) --> .then(({ results })=>this.setState( {items: results} ))
Ah - that worked! I had previously tried accessing as items.results and items['results'] but those failed obviously. Thanks for your help! For anyone else following along, here is the final code: gist.github.com/joefusaro/4e09d0949e80dcbb1a02e01405dbc360
|

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.