简体   繁体   中英

Laravel + React returns an error when tried to add a new task to an existing Project

I just learning react programming, but I kinda stuck with this error, and I already googled it but it seems I still missing some point, can someone help me with this kinda problem?

This the error I got after I tried add a new task.

在此处输入图片说明

Here is the JSX file,

import axios from 'axios'
import React, { Component } from 'react'

class SingleProject extends Component {
    constructor (props) {
        super(props)

        this.state = {
            project: {},
            tasks: [],
            title: '',
            errors: [],
        }

        this.handleMarkProjectAsCompleted = this.handleMarkProjectAsCompleted.bind(this)
        this.handleFieldChange = this.handleFieldChange.bind(this)
        this.handleAddNewTask = this.handleAddNewTask.bind(this)
        this.hasErrorFor = this.hasErrorFor.bind(this)
        this.renderErrorFor = this.renderErrorFor.bind(this)
    }

    handleMarkProjectAsCompleted () {
        const { history } = this.props

        axios.put(`/api/projects/${ this.state.project.id }`)
            .then(response => {
                history.push('/')
            })
            .catch(error => {
                this.setState({
                    errors: error.response.data.errors
                })
            })
    }

    handleMarkTaskAsCompleted (taskId) {
        axios.put(`/api/tasks/${ taskId }`).then(response => {
            this.setState(prevState => ({
                tasks: prevState.tasks.filter(task => {
                    return task.id !== taskId
                })
            }))
        })
    }

    handleFieldChange (event) {
        this.setState({
            title: event.target.value
        })
    }

    handleAddNewTask (event) {
        event.preventDefault()

        const task = {
            title: this.state.title,
            project_id: this.state.project.id
        }

        axios.post('/api/tasks', task)
            .then(response => {
                this.setState({
                    title: '',
                })
                this.setState(prevState => ({
                    tasks: prevState.tasks.concat(response.data)
                }))
            })
            .catch(error => {
                this.setState({
                    errors: error.response.data.errors
                })
            })
    }

    hasErrorFor (field) {
        return !!this.state.errors[field]
    }

    renderErrorFor (field) {
        if (this.hasErrorFor(field)) {
            return (
                <span className='invalid-feedback'>
                    <strong>{ this.state.errors[field][0] }</strong>
                </span>
            )
        }
    }

    componentDidMount () {
        const projectId = this.props.match.params.id

        axios.get(`/api/projects/${ projectId }`)
        .then(response => {
            this.setState({
                project: response.data,
                tasks: response.data.tasks,
            })
        })
        .catch(error => {
            console.log(error.response.data.message);
        });
    }

    render () {
        const { project, tasks } = this.state

        return (
            <div className='container py-4'>
                <div className='row justify-content-center'>
                    <div className='col-md-8'>
                        <div className='card'>
                            <div className='card-header'>{ project.name }</div>
                            <div className='card-body'>
                                <p>{ project.description }</p>

                                <button
                                    className='btn btn-primary btn-sm'
                                    onClick={ this.handleMarkProjectAsCompleted }
                                >
                                    Mark as completed
                                </button>

                                <hr />

                                <form onSubmit={ this.handleAddNewTask }>
                                    <div className='input-group'>
                                        <input
                                            type='text'
                                            name='title'
                                            className={ `form-control ${ this.hasErrorFor('title') ? 'is-invalid' : '' }` }
                                            placeholder='Task title'
                                            value={ this.state.title }
                                            onChange={ this.handleFieldChange }
                                        />
                                        <div className='input-group-append'>
                                            <button className='btn btn-primary'>Add</button>
                                        </div>
                                        { this.renderErrorFor('title') }
                                    </div>
                                </form>

                                <ul className='list-group mt-3'>
                                    { tasks.map(task => (
                                        <li
                                            className='list-group-item d-flex justify-content-between align-items-center'
                                            key={ task.id }
                                        >
                                            { task.title }

                                            <button
                                                className='btn btn-primary btn-sm'
                                                onClick={ this.handleMarkTaskAsCompleted.bind(this, task.id) }
                                            >
                                                Mark as completed
                                            </button>
                                        </li>
                                    )) }
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default SingleProject

And here is the controller that handle the storing

<?php

namespace App\Http\Controllers;

use App\Task;

use Illuminate\Http\Request;

class TaskController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate(['title' => 'required']);

        $task = Task::create([
            'title' => $validatedData['title'],
            'project_id' => $request->input('project_id'),
        ]);

        return $task->toJson();
    }

    public function markAsCompleted(Task $task)
    {
        $task->is_completed = true;
        $task->update();

        return response()->json('Task updated!');
    }
}

Why does the react can't find the title variable. what i do wrong in here? thank you in advance

EDIT:

the suspect that bring an error

在此处输入图片说明

I just found the problem, it's not coming from the JSX file, it's coming from the Task model,

在此处输入图片说明

I mistyped the project_id field, so Laravel refuse the mass assign data, that returns an internal server error.

after I fix the typo, the error dissapeared :D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM