Search code examples
javascriptphpjqueryajaxlaravel

Import an Excel file using AJAX and Laravel


I'm trying to import an Excel file using AJAX and Laravel in my application. the form of excel import is an inner form (form inside another form) The error handling seems to be working partially, but the error messages aren't always displayed correctly in the frontend.

THAT MY JAVASCRIPT CODE:

$(document).ready(function() {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    $('#submitUnits').on('click', function(e) {
        e.preventDefault();

        var formData = new FormData();
        formData.append('unitsFile', $('#unitsFile')[0].files[0]);
        formData.append('buildingId', $('#buildingId').val());

        var buildingId = $('#buildingId').val();
        $.ajax({
            url: '/building-units-import/' + buildingId,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(response) {

                console.log('successsss:' + response.errors);

                $('#errorMessages').empty();

                if (response.errors && response.errors.length > 0) {
                    $('#errorTable').show();
                    $.each(response.errors, function(index, error) {
                        var row = $('<tr>').appendTo('#errorMessages');
                        row.append($('<td>').text(error.row));
                        row.append($('<td>').text(error.message));
                    });
                } else {
                    $('#errorTable').hide();
                    alert('File imported successfully.');
                }
            },
            error: function(xhr) {
                console.log("error:" + xhr);
            }
        });
    });
});

after importing the Excel file: in the console, it show this: error:[object Object]

and in the network preview: it shows 422 error code with the actual Excel errors: {message: "القيمة المحددة 2.العقار غير موجودة. (و 6 أخطاء إضافية)",…} errors : [["There was an error on row 2. القيمة المحددة العقار غير موجودة."],…] 0 : ["There was an error on row 2. القيمة المحددة العقار غير موجودة."] 1 : ["There was an error on row 3. القيمة المحددة العقار غير موجودة."] 2 : ["There was an error on row 2. القيمة المحددة نوع الوحدة غير موجودة."] 3 : ["There was an error on row 3. القيمة المحددة نوع الوحدة غير موجودة."] 4 : ["There was an error on row 2. القيمة المحددة الطابق غير موجودة."] 5 : ["There was an error on row 3. القيمة المحددة الطابق غير موجودة."] 6 : ["There was an error on row 3. حقل عقد الدفاع المدني غير موجود."] message : "القيمة المحددة 2.العقار غير موجودة. (و 6 أخطاء إضافية)"

but i want to get these errors in a success case with the response.

AND, THATS MY CONTROLLER ENDPOINT:

    public function import_building_units(Request $request, $building_id)
{
    $request->validate([
        'unitsFile' => 'required|file|mimes:xlsx,xls,csv', // Use 'unitsFile' as per your form field name
    ]);


    // Access the uploaded file directly
    $file = $request->file('unitsFile');

    $import = new BuildingUnitsImport($building_id);
    Excel::import($import, $file);

    $errors = $import->getErrors();

    if (empty($errors)) {
        // Import successful, return appropriate response
        return response()->json(['success' => 'File imported successfully']);
    } else {
        // Import failed, return detailed error messages
        return response()->json(['errors' => $errors]);
    }
}

Solution

  • The following line:

    $request->validate([
        'unitsFile' => 'required|file|mimes:xlsx,xls,csv', // Use 'unitsFile' as per your form field name
    ]);
    

    Will throw a ValidationException. This will then be caught and returned based on the request type (in your case, XHR) with an error code of 422.

    If you want to change this behavior, catch the exception and return it yourself.

    try {
        $request->validate([
            'unitsFile' => 'required|file|mimes:xlsx,xls,csv', // Use 'unitsFile' as per your form field name
        ]);
    } catch (ValidationException $ex) {
        return response()->json(['errors' => $ex->errors()->all()]);
    }