Can show the full PUT request by the browser? 422 means that the validation failed.
422 Unprocessable Entity on updating record with image
Hello guys, newbee here. I want to update a record with image in the modal but when I clicked the update I have this error:
app.js:285 PUT http://www.bethyl-trade.test/api/news/1 422 (Unprocessable Entity)
this is my update function in vue js
updateNews(){
axios.put('/api/news/'+this.form.id)
.then(res => {
console.log(res);
})
.then(err => {
console.log(err)
})
},
and this is my controller
\Log::info($request->all());
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'news_image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5100'
]);
$news->where("id", $request->get("id"))->update($request->all());
What I missing or what is wrong?
there's no request on the browser... what I see the error
422 Unprocessable Entity
You have no data in the axios request; you will need a FormData instance to append the news_image, otherwise you cannot upload the image.
// you will need to get the file from the form input - I use the `id` here
let file = document.getElementById('news_image').files[0];
formData.append('title', 'Some title');
formData.append('description', 'Some description');
formData.append('news_image', file);
axios.put('/api/news/'+this.form.id, formData)
You can do it manually to work with ajax
$validator = Validator::make($request->all(), [
'title' => 'required',
'description' => 'required',
'news_image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5100'
]);
if ($validator->fails()) {
//here we check if it is an ajax request and return a more useful response :)
if($request->ajax())
{
return response()->json(array(
'success' => false,
'message' => 'There are incorect values in the form!',
'errors' => $validator->getMessageBag()->toArray()
), 422);
}
$this->throwValidationException(
$request, $validator
);
}
still I update my code like this by your suggestions still got the same error
PUT http://www.bethyl-trade.test/api/news/5 422 (Unprocessable Entity)
updateNews(){
let data = new FormData();
let file = document.getElementById('news_image').files[0];
data.append('title',this.form.title);
data.append('description',this.form.description);
data.append('news_image', file);
axios.put('/api/news/'+this.form.id, data)
.then((response)=>{
console.log(response);
})
},
Not working sir
Who are you writing to? Did you reply to me or @tykus ?
And if you replied to me, what are you getting now?
Add a console.log to interrogate the error response; see which input is causing the validation failure. Also, please note that my code snippet above was as an example, I don't know your markup, so there is no way for me to know if you have the input with id="news_image"!
axios.put('/api/news/'+this.form.id, data)
.then((response)=>{
console.log(response);
})
.catch(error => console.log(error.response)
@sinnbeck I already tried your suggestion sir but still got the error PUT http://www.bethyl-trade.test/api/news/5 422 (Unprocessable Entity)
@tykus This are the fields in modal
<div class=" modal-body">
<div class="form-group">
<label>Title</label>
<input v-model="form.title" type="text" name="title"
class="form-control" :class="{ 'is-invalid': form.errors.has('title') }" required>
<has-error :form="form" field="title"></has-error>
</div>
<div class="form-group">
<label>Description</label>
<input v-model="form.description" type="text" name="description"
class="form-control" :class="{ 'is-invalid': form.errors.has('description') }" required>
<has-error :form="form" field="description"></has-error>
</div>
<div class="form-group">
<label>News Image</label>
<input type="file" @change="imageSelected" ref="fileInput" name="news_image" id="news_image"
class="form-control" :class="{ 'is-invalid': form.errors.has('news_image') }" required>
<has-error :form="form" field="news_image"></has-error>
</div>
<div v-if="imagepreview" class="mt-3">
<img :src="imagepreview" class="figure-img img-fluid" style="max-height:100px;">
</div>
</div>
and this is my data()
data(){
return {
news_image: null,
imagepreview: null,
editmode: false,
newslist: {},
form: new Form({
id : '',
title: '',
description:'',
news_image: '',
}),
}
},
and the update()
updateNews(){
axios.put('/api/news/'+this.form.id, data)
.then((response)=>{
console.log(response);
})
},
and the controller
public function update(Request $request, News $news)
{
\Log::info($request->all());
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'news_image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5100'
]);
$news->where("id", $request->get("id"))->update($request->all());
}
@anonymouse703 please stay focused only on your PHP codes.
Does this still give you 422?
public function update(Request $request, News $news)
{
$news->where("id", $request->get("id"))->update($request->all());
}
You are not submitting the correct data, this:
axios.put('/api/news/'+this.form.id, data)
should be
axios.put('/api/news/'+this.form.id, this.form)
But, how does imageSelected do to form.news_image so that you are submiting the image as multipart form data rather than a string
@tykus I got the same error and when I console.log I have undefined.... and imageSelected is a guide for the user to see the image they upload.
Can you show the entire Vue component?
<template>
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="box">
<div class="box-header with-border">
<button type="button" class="btn btn-primary" @click="OpenModalNews">
<i class="fa fa-plus"></i> Add News
</button>
</div>
<!-- /.box-header -->
<div class="box-body">
<table class="table table-striped table-bordered dt-responsive nowrap dataTable no-footer dtr-inline collapsed" cellspacing="0" width="100%" role="grid" aria-describedby="datatable-responsive_info" style="width: 100%;">
<thead>
<tr>
<th>Date</th>
<th>Title</th>
<th class="text-center align-middle">Status</th>
<th class="text-center align-middle">Action</th>
</tr>
</thead>
<tbody>
<tr v-for="news in newslist" :key="news.id">
<td>{{news.title}}</td>
<td>{{news.description}}</td>
<td class="text-right align-middle">
<template v-if="news.status == 0 || news.status == null">
<button class="btn btn-info m-1" title="Post"><i class="glyphicon glyphicon-upload" small></i></button>
</template>
<template v-else>
<button class="btn btn-info m-1" title="Unpost" ><i class="glyphicon glyphicon-download" small></i></button>
</template>
</td>
<td class="text-right align-middle">
<button type="button" class="btn btn-primary " @click="editNews(news)" >
<i class="fa fa-edit"></i>
Edit
</button>
<button class="btn btn-danger delete-news" @click="deleteNews(news.id)">
<i class="fa fa-trash"></i>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
</div>
<!-- The Modal -->
<div class="modal fade" id="add_news_modal">
<div class="modal-dialog">
<div class="modal-content">
<form @submit.prevent="editmode ? updateNews() : addNews()" @keydown="form.onKeydown($event)" enctype="multipart/form-data">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title" v-show="!editmode">Add new news</h4>
<h4 class="modal-title" v-show="editmode">Update news info</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class=" modal-body">
<div class="form-group">
<label>Title</label>
<input v-model="form.title" type="text" name="title"
class="form-control" :class="{ 'is-invalid': form.errors.has('title') }" required>
<has-error :form="form" field="title"></has-error>
</div>
<div class="form-group">
<label>Description</label>
<input v-model="form.description" type="text" name="description"
class="form-control" :class="{ 'is-invalid': form.errors.has('description') }" required>
<has-error :form="form" field="description"></has-error>
</div>
<div class="form-group">
<label>News Image</label>
<input type="file" @change="imageSelected" ref="fileInput" name="news_image" id="news_image"
class="form-control" :class="{ 'is-invalid': form.errors.has('news_image') }" required>
<has-error :form="form" field="news_image"></has-error>
</div>
<div v-if="imagepreview" class="mt-3">
<img :src="imagepreview" class="figure-img img-fluid" style="max-height:100px;">
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<div class="form-group pb-xl-5 pull-right">
<button :disabled="form.busy" v-show="!editmode" type="submit" class="btn btn-primary">Add News</button>
<button :disabled="form.busy" v-show="editmode" type="submit" class="btn btn-info">Update Me</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
news_image: null,
imagepreview: null,
editmode: false,
newslist: {},
form: new Form({
id : '',
title: '',
description:'',
news_image: '',
}),
}
},
mounted(){
this.getNewsList();
},
methods:{
getNewsList(){
axios.get('/api/news').then(response => this.newslist = response.data);
},
editNews(news){
this.editmode = true;
this.form.reset();
this.form.fill(news);
$('#add_news_modal').modal('show');
},
updateNews(){
let data = new FormData();
data.append('title',this.form.title);
data.append('description',this.form.description);
data.append('news_image',this.news_image);
this.form.put('api/news/'+this.form.id ,data)
.then((response)=>{
console.log(response);
swal.fire({
icon: 'success',
title: 'News updated successfully'
})
this.loadTableData()
$('#add_news_modal').modal('hide');
})
.catch(()=>{
console.log("Error.....")
})
},
OpenModalNews(){
this.editmode = false;
this.form.reset();
$('#add_news_modal').modal('show');
},
imageSelected(e){
this.news_image = e.target.files[0];
let reader = new FileReader();
reader.readAsDataURL(this.news_image);
reader.onload = e => {
this.imagepreview = e.target.result;
};
},
addNews(){
let data = new FormData();
data.append('title',this.form.title);
data.append('description',this.form.description);
data.append('news_image',this.news_image);
axios.post('/api/news',data)
.then((response)=>{
$('#add_news_modal').modal('hide');
this.getNewsList();
})
.catch(error => this.form.errors.record(error.response.data));
},
deleteNews(id){
// alert('Deleted');
swal.fire({
title: 'Are you sure?',
text: 'You will not be able to recover this imaginary file!',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'No, keep it'
}).then((result) => {
if (result.value) {
console.log(id);
axios.delete('api/news/'+id).then(response => {
swal.fire(
'Deleted!',
'The record has been deleted.',
'success'
);
this.getNewsList();
});
} else if (result.dismiss === swal.DismissReason.cancel) {
swal.fire(
'Cancelled',
'The record is cancelled',
'error'
)
}
})
}
}
};
</script>
Create new data, edit and delete is okay... that update is where I stuck.....
@anonymouse703 hey so as it appears youre using Laravel, I'm also using it in a college project atm and came across the same error, my tutor just solved it for me, turns out Laravel PUT isnt native to Laravel, or at least they dont deal with put image requests properly, essentially what you need to do is change the PUT request to a POST request and put "_method: post" into your headers.
should be axios.post('api/news/' +form, data) headers: { _method : "put" } .then etc.......
hopefully this works, or at least helps a bit, crazy error, took us days of toying and we only figured it because our lecturer knew it lmao
Please or to participate in this conversation.