LSheNNawY's avatar

"PUT" Ajax request 422 error

I'm working on updating data with file upload using ajax and every time validation error says that all fields are required although the fields are not empty.

this is my js Code:

function save() {
    var data = new FormData($('.form'));
    $.ajax({
        url: ajaxUrl,
        method : ajaxMethod,
        data: data,
        processData: false,
        contentType: false,
    }).done(...).fail(function(response) {
        console.log(response.responseText);
    });
}

and laravel controller method is:

public function saveCountry(CountriesRequest $request)
    {
        if ($request->ajax()) {
            $id = $request->id ?? null;
            // updating
            if ($id) {
                $country = Country::find($id);
                // if the user didn't update the icon
                if ($request->icon == ''){
                    $country->update($request->except(['icon']));
                }
                else {
                    $countryIcon = $country->icon;
                    $country->update([
                        'name_en'   => $request->name_en,
                        'name_ar'   => $request->name_ar,
                        'code'      => $request->code,
                        'symbol'    => $request->symbol,
                        'icon'      => Up::imageUpload($request, 'icon', 'public/countries/icon', true),
                    ]);
                    // dlete old icon
                    Storage::delete($countryIcon);
                }
            }
            // new country 
            else {
                Country::create([
                        'name_en'   => $request->name_en,
                        'name_ar'   => $request->name_ar,
                        'code'      => $request->code,
                        'symbol'    => $request->symbol,
                        'icon'      => Up::imageUpload($request, 'icon', 'public/countries/icon', true),
                    ]
                );
            }
        }
    }

Notice : Up: is a custom class for uploading files

the error message is:

"{"message":"The given data was invalid.","errors":{"name_en":["The Name in English field is required."],"name_ar":["The Name in Arabic field is required."],"code":["The Code field is required."],"symbol":["The Symbol field is required."]}}"

the creating request is working very well but the update request not working, I checked laravel code and I think it's ok

0 likes
21 replies
Cronix's avatar

Do you mean 422? If it's 422, it's a form validation error. Did you check the fail() method for a response?

If that's not what you mean, you'll have to give more info as your code is pretty sparse.

What is "thisEle" and where does it come from? Seems undefined. Same with ajaxUrl and ajaxMethod....

LSheNNawY's avatar

I'm sorry, it's 422 I've edited it, ajaxUrl and ajaxMethod are just variables for the request url and request method ['put']

tykus's avatar

Have you inspected the PUT request to ensure that the data is being sent as expected?

What validation rules have you defined for the request? Did you specify your own validation messages? Maybe share the server-side code since the request obviously is hitting the server.

Cronix's avatar

Ok, did you check what I said? If it's a 422 response, it's sending back the form validation errors as json. So, you should display them to the user so they know what they did wrong on the form.

Unless your form has a file input, I'd suggest getting the form data with var data = $('.form').serialize();. I'm hoping you only have one form on the page, as you're using a class to target the form instead of an id.

tykus's avatar

The controller method is irrelevant if you are using Form Requests; what does CountriesRequest look like?

What does data actually look like in your javascript?

Hitostacha's avatar

Are you appending '_method': 'PUT' in your form? When you're using FormData you're only able to use POST.

LSheNNawY's avatar

Countries request rules method

public function rules()
    {
        return [
            'name_en'   => 'required|regex:/^[a-zA-Z0-9 -]+/|min:3',
            'name_ar'   => 'required|regex:/^[\p{Arabic} -]+/u|min:3',
            'code'      => 'required|regex:/^[+0-9]/',
            'symbol'    => 'required|regex:/[a-zA-Z]+/|min:2',
            'icon'      => 'nullable|mimes:jpeg,jpg,bmp,png',
        ];
    }
Cronix's avatar

Check the dev tools in your browser. Go to the network tab. Make your request. Click on the ajax request in the tab. Check the headers/params tabs that appear on the right to see what the actual data you are sending to the controller is.

Did you try my suggestion on using

var data = $('.form').serialize();

?

LSheNNawY's avatar

I've used serialize() method and not working too.

and this is all info.

General:
Request URL: http://lara-vue-ecom.test/admin/countries/saveCountry
Request Method: PUT
Status Code: 422 Unprocessable Entity
Remote Address: 127.0.0.1:80
Referrer Policy: no-referrer-when-downgrade


Responce Headers:
Cache-Control: no-cache, private
Connection: Keep-Alive
Content-Length: 239
Content-Type: application/json
Date: Fri, 24 Aug 2018 17:19:37 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.29 (Ubuntu)
Set-Cookie: XSRF-TOKEN=eyJpdiI6Ik1QeFRkcE4zNjE3aUJqN1RITVVWVkE9PSIsInZhbHVlIjoiajM4dWR2bjN0emQ0ckNIY0ZpaEpHRUx3UDMrVElOa2QyQTN0ZEd5NkM0NnNTOGt5SmpObFpyUlVUTlNJZEk1cSIsIm1hYyI6IjkwOTNmNjNmZGJlMzk3MzIxODdjOGViMmE3NzM4MjVlY2Q1Y2E0ZDFiMjNiYjhiYzNjOGRhMDYxODIxNDc5OGEifQ%3D%3D; expires=Fri, 24-Aug-2018 19:19:37 GMT; Max-Age=7200; path=/
Set-Cookie: ecommerce_session=eyJpdiI6Ino2MjZYMUpYaTE3dHlzNGgwQnlDWnc9PSIsInZhbHVlIjoia0lOZW5IXC9TM0lcL3JCWnlnRFdHeUJ4bmo2b2xTNU1pdVFWNFhGMW1aMTJuVURMZmFZQmNBTnpLd2FscTdEZmFEIiwibWFjIjoiNTcxYWFhMWJlZjZhYjc1NTA0Yzk3NzkxY2NhNmIyZmE5ZjRmZDUyODIxMWQ1ODI4YjljMWU0NTM3Y2Y3N2ZlMiJ9; expires=Fri, 24-Aug-2018 19:19:37 GMT; Max-Age=7200; path=/; httponly


Request Headers:
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,und;q=0.8,ar;q=0.7
Connection: keep-alive
Content-Length: 771
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypD8Tw4ZYyrufSHBd
Cookie: remember_admin_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6ImZLMTI1S21ZYTJxd1F0c1owS29DV2c9PSIsInZhbHVlIjoicDhTU3poNkRocTVFaUhqNXFxYzhGTm1RbjYyZzFUdVdyK0Y5NzdidEpcLzdTV0Fzb3VnRTZsTEczZFVVQlNUNmVMamYyTlJncWh1dEV6V3hIaVBpY3FMTUJaS01NRHlQeXY3YU44MUdqcVlNV3JBUDVQWFU3U0N5NVlMb2NHdnhOc0J6ZkpYd2FWbERlRUNqTWoyZytGMG1BK0ZUKzc3U09hcXcyZldta2hyYz0iLCJtYWMiOiIzYjBjOGYyNzUyNzBlNjkyYzg3OTZlZWQ4OGNmZjUxZjJiMWM0NjQwZjJkM2Y4ZDQ4YzlhNmU3NmRmNzMwY2Y5In0%3D; XSRF-TOKEN=eyJpdiI6Im1mVjZwYkNSQXZUeTdyMm0wd0p2SVE9PSIsInZhbHVlIjoiNjc0WHo0ZXIxNGd0dHBvK0d5dlNcL05jZXY5aVVzXC9vKzdrYnZEaktBcnh4b25WZGZzK3hIUlJNOVlhNnpiZmExIiwibWFjIjoiNmNiNTYzNDgwMGI1Y2JiYmMyYTI2MTkwODIzZTgwODFhNTJiMmQ3MmE2OWNkNmZlMjQwMjZmOGJjNTdkZjBhYiJ9; ecommerce_session=eyJpdiI6ImViSFlFQUtuS08wMXlWendmUWYrQ0E9PSIsInZhbHVlIjoiQTJFU0RnVGY2Zml3OVVQamppc25YbXp0OWFiaGUraDRUd2R1WTJnV0hIaFlINFo4Q1dlRDRIaHl3NFBacFFcL1UiLCJtYWMiOiJhMjYxZTBiNmNiMWM5ZmJkMzlmYzVjN2JlNjFiOTVmZDE0NGY4YmRmMGYxMzU5YTZkNjcwZmU3ZDJlMzcxMTU5In0%3D

Host: lara-vue-ecom.test
Origin: http://lara-vue-ecom.test
Referer: http://lara-vue-ecom.test/admin/countries
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
X-CSRF-Token: ppFEoEhG5aSCyWN9xjrxzQUEzylhVPoJmkiT3Xoo
X-Requested-With: XMLHttpRequest


Request Payload:
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="name_en"

Spain
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="name_ar"

اسبانيا
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="code"

427
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="symbol"

ES
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="icon"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="id"

4
------WebKitFormBoundarypD8Tw4ZYyrufSHBd
Content-Disposition: form-data; name="_method"

PUT
------WebKitFormBoundarypD8Tw4ZYyrufSHBd--
Cronix's avatar

remove contentType: false, from your ajax settings.

Cronix's avatar

Is your js in a view, or a standalone .js file? If you're not using laravel mix and cache-busting, are you force-refreshing your browser or clearing the cache? The browser might not be reloading your changes (if it's in a js file)

LSheNNawY's avatar

it's a standalone file and I force-refreshing the browser.

Cronix's avatar

Ok, so for now ,I'd remove your validation, and just return the input.

public function saveCountry(Request $request) // change to Request
{
    return response()->json($request->all());

    // rest of code...

Then check the response of the ajax request again in the browsers dev tools.

jlrdw's avatar

You also probably need to clear cache between programming changes.

suxe's avatar

Hi LSheNNawY,

I had the same problem and it seems is a little missunderstanding about how to indicate the param names in the rules() method.

For json requests we should consider using the nested mode syntax in the return array; in this case, just adding the variable name 'data', within you passed the json in your ajax request.

It should work like that:

public function rules()
    {
        return [
            'data.name_en' => 'required|regex:/^[a-zA-Z0-9 -]+/|min:3',
            'data.name_ar' => 'required|regex:/^[\p{Arabic} -]+/u|min:3',
            'data.code' => 'required|regex:/^[+0-9]/',
            'data.symbol' => 'required|regex:/[a-zA-Z]+/|min:2',
            'data.icon' => 'nullable|mimes:jpeg,jpg,bmp,png',
        ];
    }

petritr's avatar

@LSheNNawY What are you missing is the csrf

    $.ajax({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
       ....
      .....
    });

Just add this to ajax (of course you need the csrf in the meta tag)

LSheNNawY's avatar
LSheNNawY
OP
Best Answer
Level 1

Thank you all, I could fix it.

the problem was that I had to set the (ajax method) to POST not PUT and add {{ method_field('PUT') }} to the form.

marcosdipaolo's avatar

this is funny, at this point of the game, put request should be accepted when sending multipart/form-data

Please or to participate in this conversation.