Reputation: 43
I'm getting this compile error, but I'm unclear about what's undefined. This all looks like it should work, or at least not produce errors, but maybe I'm missing something obvious? Any assistance would be much appreciated. I'm happy to upload any additional code that might shed some light on the problem.
←→1 of 2 errors on the page
TypeError: Cannot read property 'map' of undefined
Persons.render
src/Components/Persons.jsx:14
11 | }
12 |
13 | render() {
> 14 | let personsList = this.props.persons.map( ( persons, index) => {
| ^ 15 | return <div className="personsListLinks"><li key={index}><Link to={`/api/persons/${persons.id}`}>{persons.name}</Link></li></div>
16 | })
17 | return (
View compiled
This is the Component:
import { BrowserRouter as Link } from "react-router-dom";
class Persons extends Component {
constructor(props){
super(props)
this.state = {
persons: '',
personsList: ''
}
}
render() {
let personsList = this.props.persons.map( ( persons, index) => {
return <div className="personsListLinks"><li key={index}><Link to={`/api/persons/${persons.id}`}>{persons.name}</Link></li></div>
})
return (
<div className="PersonsList">
<h1>Persons</h1>
{personsList}
</div>
)
}
}
export default Persons;
And, App.jsx...
import './App.css';
import Signup from './Signup';
import Login from './Login';
import UserProfile from './UserProfile';
import { BrowserRouter as Router, Route, Link, Redirect } from "react-router-dom";
import axios from 'axios';
import PersonsShow from './Components/PersonsShow';
import Persons from './Components/Persons';
import { set } from 'mongoose';
class App extends Component {
constructor(props) {
super(props)
this.state = {
token: '',
user: null,
errorMessage: '',
lockedResult: '',
persons: [],
personality: [],
quotes: []
}
this.liftTokenToState = this.liftTokenToState.bind(this)
this.checkForLocalToken = this.checkForLocalToken.bind(this)
this.logout = this.logout.bind(this)
this.handleClick = this.handleClick.bind(this)
this.addNewPerson = this.addNewPerson.bind(this)
// this.addQuote = this.addQuote.bind(this)
}
checkForLocalToken() {
// Look in localStorage for the token
let token = localStorage.getItem('mernToken')
if (!token || token === 'undefined') {
// There is no token
localStorage.removeItem('mernToken')
this.setState({
token: '',
user: null
})
} else {
// Found a token, send it to be verified
axios.post('/auth/me/from/token', {token})
.then( res => {
if (res.data.type === 'error') {
localStorage.removeItem('mernToken')
this.setState({errorMessage: res.data.message})
} else {
// Put token in localStorage
localStorage.setItem('mernToken', res.data.token)
// Put token in state
this.setState({
token: res.data.token,
user: res.data.user
})
}
})
}
}
componentDidMount() {
this.checkForLocalToken()
this.getPersons()
}
getPersons = () => {
axios.get('/persons')
.then(res => {
this.setState({
persons: res.data
})
})
}
liftTokenToState({token, user}) {
this.setState({
token,
user
})
}
logout(){
// Remove the token from localStorage
localStorage.removeItem ('mernToken')
// Remove the user and token from state
this.setState({
token: '',
user: null
})
}
handleClick(e) {
e.preventDefault()
// axios.defaults.headers.common['Authorization'] = `Bearer ${this.state.token}`
let config = {
headers: {
Authorization: `Bearer ${this.state.token}`
}
}
axios.get('/locked/test', config).then( res => {
// console.log("this is the locked response:" , res);
this.setState({
lockedResult: res.data
})
})
}
handleNewPersonClick(person) {
this.setState({
person: person
})
}
addNewPerson(e) {
e.persist()
e.preventDefault()
let user = this.props.user
let person = this.props.persons
axios.post(`/api/user/:id/person${user._id}/`, {
name: e.target.name
}).then(res => {
axios.get(`/api/user/${user._id}/persons`).then(res => {
this.setState({persons: res.data})
})
})
}
render() {
let user = this.state.user
let contents;
if (user) {
contents = (
<Router>
<Route exact path='/' render= {() => <Redirect to='/persons' /> } />
<Route exact path='/' render={() => <Persons persons={this.state.persons} user={this.state.user} logout={this.logout} />}/>
{/* <Route path="/persons/:pid" render={(props) => <PersonsShow person={this.state.persons} addItem={this.addItem} user={user} logout={this.logout} {...props} />}/> */}
{/* <Route path="/cart" render={() => <CartPage cart={this.state.cart} />}/> */}
<UserProfile user={user} logout={this.logout} />
<Persons person={this.state.persons} addItem={this.addItem} user={user} logout={this.logout}/>
{/* <PersonsShow user={user} /> */}
{/* <Persons user={user} /> */}
{/* <p><a onClick={this.handleClick}>Test the protected route...</a></p> */}
<p>{this.state.lockedResult}</p>
</Router>
)
} else {
contents = (
<>
<Signup liftToken={this.liftTokenToState} />
<Login liftToken={this.liftTokenToState} />
</>
)
}
return (
<div className="App">
<header><h1>Welcome to Judge-O-Matic!</h1></header>
<div className="content-box">
{contents}
</div>
</div>
)
}
}
export default App;
I've tried rewriting as a functional component with similar results.
Upvotes: 0
Views: 526
Reputation: 2667
You have a typo:
<Persons person={this.state.persons} addItem={this.addItem} user={user} logout={this.logout}/>
should be
<Persons persons={this.state.persons} addItem={this.addItem} user={user} logout={this.logout}/>
Please note the s
at the end of the first prop.
Upvotes: 3