Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anonymouse703's avatar

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?

0 likes
16 replies
laracoft's avatar

Can show the full PUT request by the browser? 422 means that the validation failed.

anonymouse703's avatar

there's no request on the browser... what I see the error 422 Unprocessable Entity

tykus's avatar

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)
Sinnbeck's avatar

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

            );
}
anonymouse703's avatar

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);
          })
      },
Sinnbeck's avatar

Who are you writing to? Did you reply to me or @tykus ?

And if you replied to me, what are you getting now?

tykus's avatar

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)
	
anonymouse703's avatar

@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());
    }
laracoft's avatar

@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());
}
tykus's avatar

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

anonymouse703's avatar

@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.

tykus's avatar

Can you show the entire Vue component?

anonymouse703's avatar

@tykus

<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>
                      &nbsp;Edit
                    </button>


                    <button class="btn btn-danger delete-news" @click="deleteNews(news.id)">
                      <i class="fa fa-trash"></i>
                      &nbsp;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">&times;</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.....

xJustinJPD's avatar

@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.