Reputation: 93
I have been fighting this error in my code, I am creating a dropdown menu that maps the collections in my Firestore database. It is rendering the courses however, when I click on one, it gives me the following error:
Here is my code:
import React, { Component } from 'react'
import firebase from 'firebase/app'
import './add.css'
export default class add extends Component {
state = {
course: 'TestCourse1',
question: '',
questionType: 'MultipleChoice',
correctAnswer: '',
wrongAnswer: '',
wrongAnswer2: '',
wrongAnswer3: '',
courses: []
}
componentDidMount() {
let db = firebase.firestore()
db.collection('courses').get().then(snapshot => {
const courses = []
snapshot.docs.forEach(doc => {
const data = doc.data()
courses.push(data)
})
this.setState({courses})
}).catch(error => { console.error(error) })
}
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value,
})
}
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state)
}
render() {
const {courses} = this.state
return (
<div className = "Container">
<div className = "AddQuestion">
<h1> Add a question </h1>
<div className = "AddQuestionFormContainer">
<form>
<label htmlFor = "courses"> Courses</label> <br/>
<select name = "course" id = "courses" onChange = {this.handleChange} value = {this.state.course}>
{
courses && courses.map(course => {
return <option value = {course.courseName} key = {course.courseName}> {course.courseName}</option>
})
}
</select> <br/><br/>
<label htmlFor = "question"> Question </label> <br/>
<input type = "text" id = "question" placeholder = "Enter your question" onChange={this.handleChange}/>
<br/><br/>
<label htmlFor = "question"> Question Type </label><br/>
<select name = "questionType" id = "questionType" onChange={this.handleChange} value = {this.state.questionType} >
<option value = "MultipleChoice" > Multiple Choice</option>
<option value = "TrueOrFalse"> True or False </option>
</select>
<br/><br/>
<label htmlFor = "correctAnswer"> Correct Answer</label> <br/>
<input type = "text" id = "correctAnswer" placeholder = "Correct Answer" onChange={this.handleChange}/>
<br/><br/>
<label htmlFor = "wrongAnswer"> Wrong Answers </label><br/>
<input type = "text" id = "wrongAnswer" placeholder = "Wrong Answer" onChange={this.handleChange} /><br/>
<input type = "text" id = "wrongAnswer2" placeholder = "Wrong Answer" onChange={this.handleChange} /><br/>
<input type = "text" id = "wrongAnswer3" placeholder = "Wrong Answer" onChange={this.handleChange} /><br/> <br/>
<button onClick = {this.handleSubmit}> Submit </button>
</form>
</div>
</div>
</div>
)
}
}
The value of the object is rendering to my state fine, it's just when I go to select an option in my dropdown it returns the error!
Any help would be much appreciated.
EDIT 1
After adding a console.log in my componentDidMount(), this is what is returned
CODE
componentDidMount() {
let db = firebase.firestore()
db.collection('courses').get().then(snapshot => {
const courses = []
snapshot.docs.forEach(doc => {
const data = doc.data()
courses.push(data)
console.log(courses)
})
this.setState({courses})
}).catch(error => { console.error(error) })
}
Console.log
Upvotes: 0
Views: 703
Reputation: 6736
This issue is happening because, In the state you are defining courses
as an array. But while handleChange
overriding it into a string.
handleChange = (e) => {
// Here overriding the value of courses to a string
this.setState({
[e.target.id]: e.target.value //targetId is `courses` and the value is a string
})
}
According to my understanding, you will have to track the selected course. For that change the id
of select
to course
<select
name="course"
id="course"
onChange={this.handleChange}
value={this.state.course}
>
sample demo:- https://codesandbox.io/s/black-butterfly-2shjv?file=/src/App.js
Please let me know if you are facing any issues.
Upvotes: 1
Reputation: 66
First thing make sure your service returning an array to 'courses' and I recommend you to write like this
courses.length && courses.map(course => {
return <option value = {course.courseName} key={course.courseName}>
{course.courseName}
</option>});
Upvotes: 0