I am new to React and javascript so please bear with me
I am building a basic todolist app
Main App.js is the following
class App extends Component {
constructor(props) {
super(props);
this.fetchTasks = this.fetchTasks.bind(this)
this.strikeUnstrike = this.strikeUnstrike.bind(this)
};
state = {
todoList: [],
activeItem: {
id: null,
title: '',
completed: false,
},
editing: false,
}
componentDidMount() {
this.fetchTasks()
}
// pull the list of tasks from the API
fetchTasks() {
axios.get('http://127.0.0.1:8000/api/task-list/')
.then( response => {
this.setState({ todoList: response.data })
} )
}
strikeUnstrike(task) {
task.completed = !task.completed
let url = `http://127.0.0.1:8000/api/task-update/${task.id}/`
let data = {'completed': task.completed, 'title':task.title}
axios.post( url, data)
.then(response => this.fetchTasks() )
}
render() {
return (
<div className='container'>
<div id ='task-container'>
<TaskList
tasks = {this.state.todoList}
taptask = {this.strikeUnstrike(task)}
// taptask = {() => this.strikeUnstrike(task)} // also tried this
/>
</div>
</div>
)
}
}
export default App;
My TaskList.js component looks like the following
import React from 'react';
const tasklist = (props) => {
return (
<div id='list-wrapper'>
{props.tasks.map((task, index) => {
// console.log('the task X is :', task) // works
// console.log('the passed prop is :', props.taptask) //works
return (
<div key={index} className="task-wrapper flex-wrapper">
<div onClick={props.taptask(task)} style={{flex:7}} >
{ task.completed == false ? (
<span>{task.title}</span>
) : (
<strike>{task.title}</strike>)}
</div>
<div style={{flex:1}}>
<button
// onClick={ props.editClick(task)}
className="btn btn-sm btn-outline-info">Edit</button>
{console.log('working')}
</div>
<div style={{flex:1}}>
<button
// onClick = {props.deleteClick(task)}
className="btn btn-sm btn-outline-dark">-</button>
</div>
</div>
)
})}
</div>
)
}
export default tasklist;
Yet, I'm getting the following error
TypeError: Cannot read property 'completed' of undefined
App.strikeUnstrike
src/frontend/src/App.js:134
131 | // this basically allows you to check off an item as complete by clicking on it
132 | // strikeUnstrike = (task) => {
133 | strikeUnstrike(task) {
> 134 | task.completed = !task.completed
| ^ 135 | console.log('TASK :' , task.completed)
136 |
137 | let csrfoken = this.getCookie('csrftoken')
View compiled
taptask
src/frontend/src/App.js:166
163 |
164 | <TaskList
165 | tasks = {this.state.todoList}
> 166 | taptask = {() => this.strikeUnstrike()}
| ^ 167 | // taptask = {this.strikeUnstrike(task)}
168 | // editClick = {()=> this.startEdit(task)}
169 | // deleteClick = {()=> this.deleteItem(task)}
View compiled
(anonymous function)
src/frontend/src/Components/TaskList/TaskList.js:15
12 | <div key={index} className="task-wrapper flex-wrapper">
13 |
14 |
> 15 | <div onClick={props.taptask(task)} style={{flex:7}} >
| ^ 16 |
17 | { task.completed == false ? (
18 | <span>{task.title}</span>
View compiled
I am aware of bindings and I've tried several approaches (using this.functionName.bind(this) in the constructor and the arrow function approach) however I'm not able to resolve the issue. Any help would be much appreciated.