Reputation:
I use Axios to update my API. I send a request with the input and I get the response from the API whether it works or not. I started implementing an image feature on my website and had quite some issues since then. I had to put everything in a form data, which I had never done before and send it. On the "POST" page, everything seems to work fine. I send everything and it works as it should. However, on my "PATCH" page, whatever I send, it tells me that the input are empty and that they need a value. I check on Laravel Telescope and the payload seems empty. I tried to compare the two pieces of code (AddOrganism works, OrganismSettings doesn't) and I can't find my error.
Can you help me ?
This one works :
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'
import Dashboard from '../Dashboard';
import * as Cookies from 'js-cookie'
import ErrorContainer from '../../components/ErrorContainer';
import axios from 'axios'
import { createOrUpdateFromFlatCoordinates } from 'ol/extent';
export class AddOrganism extends Component {
constructor(props) {
super(props);
this.state = {name: '', description: '', address: '', picture: null}
this.handleChange = this.handleChange.bind(this);
this.handleChangePicture = this.handleChangePicture.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
var places = require('places.js');
var placesAutocomplete = places({
appId:",
container: document.querySelector('#address-input')
});
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleChangePicture(event) {
this.setState({picture: event.target.files[0]})
}
handleSubmit(e) {
e.preventDefault();
var formData = new FormData();
formData.append('name', this.state.name);
formData.append('description', this.state.description);
formData.append('address', this.state.address);
formData.append('picture', this.state.picture);
var token = Cookies.get('token');
axios.post('http://localhost:8000/api/organism/create',formData, {
headers: {
"Accept": 'application/json',
"Authorization": `Bearer ${token}`
}
}).then(
(success) => {
this.setState({loading: false});
this.props.history.push('/organisme')
}, (error) => {
this.setState({errors : error.response.data.data})
if(error.response.data.redirect != "") {
this.props.history.push(error.response.data.redirect)
}
}
)
}
render() {
return (
<Dashboard>
<section className="section has-text-centered">
<div className="column is-offset-1 is-10">
<h1 className="title is-size-1 register-title">Enregistrement d'un organisme</h1>
<section className="section organism-register">
<form encType="multipart/form-data" className="user-form fullbox-form" method="POST" onSubmit={this.handleSubmit}>
<div className="has-text-left input-fixer">
<label className="is-size-4">Nom de l'organisme : </label><input type="text" name="name" placeholder="Nom de l'organisme" value={this.state.name} onChange={this.handleChange}/>
<label className="is-size-4">Description de l'organisme : </label><textarea name="description" placeholder="Description de l'organisme" value={this.state.description} onChange={this.handleChange}/>
<label className="is-size-4">Adresse de l'organisme : </label><input id="address-input" type="text" name="address" value={this.state.address} onChange={this.handleChange}></input>
<label className="is-size-4">Ajouter le logo de votre organisme : </label>
<input type="file" name="picture" onChange={this.handleChangePicture} />
</div>
<ErrorContainer errors={this.state.errors} />
<button className="button is-primary has-text-left">Soumettre le formulaire</button>
</form>
</section>
</div>
</section>
</Dashboard>
)
}
}
export default withRouter(AddOrganism)
This one doesn't work :
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'
import Dashboard from '../Dashboard'
import Axios from 'axios'
import * as Cookies from 'js-cookie'
import ErrorContainer from '../../components/ErrorContainer'
export class OrganismSettings extends Component {
constructor(props) {
super(props);
this.state = {loading: true, organism: [], name: "", description: "", address: "", picture: null}
this.getOrganism = this.getOrganism.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChangePicture = this.handleChangePicture.bind(this);
}
componentDidMount() {
this.getOrganism();
var places = require('places.js');
var placesAutocomplete = places({
container: document.querySelector('#address-input')
});
}
getOrganism() {
Axios.get('http://localhost:8000/api/organism/settings', {headers: {Accept: 'application/json', Authorization: 'Bearer ' + Cookies.get('token')}})
.then((success) => {
var organism = success.data.data.organism;
this.setState({organism: success.data.data.organism, loading: false})
this.setState({name: organism.name, description: organism.description, address: organism.address})
}, (error) => {
this.props.history.push('/organisme/creation')
})
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleChangePicture(event) {
this.setState({picture: event.target.files[0]})
}
handleSubmit(e) {
e.preventDefault();
var formData = new FormData();
formData.append('name', this.state.name);
formData.append('description', this.state.description);
formData.append('address', this.state.address);
formData.append('picture', this.state.picture);
var token = Cookies.get('token');
Axios.patch('http://localhost:8000/api/organism/settings', formData, {
headers: {
"Accept": 'application/json',
"Authorization": `Bearer ${token}`,
}
}).then(
(success) => {
this.setState({loading: false});
//this.props.history.push('/organisme')
}, (error) => {
this.setState({errors : error.response.data.data})
if(error.response.data.redirect != "") {
this.props.history.push(error.response.data.redirect)
}
}
)
}
render() {
return (
<Dashboard loading={this.state.loading}>
<section className="section has-text-centered">
<div className="column is-offset-1 is-10">
<h1 className="title is-size-1 register-title">Paramètres de {this.state.name}</h1>
<section className="section organism-register">
<form encType="multipart/form-data" className="user-form fullbox-form" method="POST" onSubmit={this.handleSubmit}>
<div className="has-text-left input-fixer">
<label className="is-size-4">Nom de l'organisme : </label><input type="text" name="name" placeholder="Nom de l'organisme" value={this.state.name} onChange={this.handleChange}/>
<label className="is-size-4">Description de l'organisme : </label><textarea name="description" placeholder="Description de l'organisme" value={this.state.description} onChange={this.handleChange}/>
<label className="is-size-4">Adresse de l'organisme : </label><input id="address-input" type="text" name="address" value={this.state.address} onChange={this.handleChange}></input>
<label className="is-size-4">Ajouter le logo de votre organisme : </label>
<input type="file" name="picture" onChange={this.handleChangePicture} />
</div>
<ErrorContainer errors={this.state.errors} />
<button className="button is-primary has-text-left">Soumettre les changements</button>
</form>
</section>
</div>
</section>
</Dashboard>
)
}
}
export default withRouter(OrganismSettings)
Upvotes: 0
Views: 2601
Reputation: 9059
It is a known bug on PHP, Symfony and Laravel as well, a workaround is to append _method
param with PATCH
or PUT
value to your formdata
and use axios.post
instead:
formData.append('_method', 'PATCH');
Axios.post(
'http://localhost:8000/api/organism/settings',
formData,
//{...
Check this issue on Laravel repo for more info: https://github.com/laravel/framework/issues/13457#issuecomment-340156084
Upvotes: 4