1

Llevo horas probando distintas cosas y no entiendo como realizar esto. Tengo un formulario por el cual quiero enviar datos con ajax, y en caso de que algun input venga vacio mostrar el tipico aviso de completar campos. Estoy usando laravel 10 para ello cree un Request para recibir los datos lo hare lo mas corto posible.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

use Illuminate\Http\Exceptions\HttpResponseException;

class PostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {

        //dd($this->all());
        return [
            'title_post' => 'required',

        ];


    }



   
    protected function failedValidation(Validator $validator)
    {
        $errors = $validator->errors();
        $isEmpty = false;

        // Verificar si hay algún campo vacío
        foreach ($this->all() as $field => $value) {
            if (empty($value)) {
                $isEmpty = true;
                $errors->add($field, 'errores');
            }
        }

        // Si hay campos vacíos, lanzar una excepción con la respuesta JSON de error
        if ($isEmpty) {
            throw new HttpResponseException(response()->json([
                'status' => false,
                'errors' => $errors,
                'message' => 'Por favor complete todos los campos obligatorios.',
            ], 422));
        }
    }
}

mi controlador es


    public function store(PostRequest $request)
    {

        return $request;

    }

Y mi ajax

function sendAjaxRequest(method, url, data, callback) {
    var request = new XMLHttpRequest();
    request.open(method, url, true);
    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            if (request.status === 200) {
                console.log(request.responseText);
                callback(JSON.parse(request.responseText));
            } else {
                console.error("Error en la solicitud: " + request.statusText);
            }
        }
    };
    request.send(data);
}


////guardar 

function save() {
    const formSave = document.getElementById("blog_form");
    formSave.addEventListener("submit", function (e) {
        e.preventDefault();
        var formData = new FormData(formSave);
        var ajaxUrl = formSave.getAttribute("data-ajax-url");
        const test = base_url + "/admin/post/store";
        sendAjaxRequest("POST", ajaxUrl, formData, function (response) {
            if (response.status) {

            } else {

            }
        });
    });
}
save();

y mi formulario

<form
    id="blog_form"
    method="POST"
    data-ajax-url="{{ route('post.store') }}"
    action="{{ route('post.store') }}"
    enctype="multipart/form-data"
    class="form d-flex flex-column flex-lg-row">
    @csrf

    <input type="text" id="title_post" name="title_post" />
    <button type="submit" id="add_blog_submit" class="btn btn-primary">
        <span class="indicator-label">Guardar</span>
    </button>
</form>

Lo unico que consigo es error 422 Unprocessable Content como lograria enviar datos por ajax y en caso de algun campo este vacio mandar con json algun mensaje. Se que sin usar ajax simplemente redirige a otra pagina y muestra los avisos pero en este caso no consigo realizar esto con ajax.

0

1 respuesta 1

1

Por el lado de laravel, si la solicitud entrante está esperando una respuesta JSON, formateará automáticamente los mensajes de error y devolverá una respuesta HTTP de entidad no procesable 422.
Dicho eso. lo que hiciste en la funcion failedValidation(... no es necesario. Tu solo defines el array de reglas en la función rules y laravel se ocupa de hacer todo lo demás automáticmente.

Entonces, a tu lamada ajax, tendrias que agregale el header request.setRequestHeader('Accept', 'application/json'); para que laravel se entere que la solicitud espera un json como respuesta.
Y luego manejar la respuesta en el js del ajax.

function sendAjaxRequest(method, url, data, callback) {
    var request = new XMLHttpRequest();
    request.open(method, url, true);

    // agrega el header aqui
    request.setRequestHeader('Accept', 'application/json');

    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            if (request.status === 200) {
                console.log(request.responseText);
                callback(JSON.parse(request.responseText));
            } 
            // obten el json de la respuesta aqui si el status es 422
            if (request.status === 422) {
                console.error(request.responseText);
                // lo esperable es que te devuelva algo asi
                // {"message":"The title post field is required.","errors":{"title_post":["The title post field is required."]}}
            }
        }
    };
    request.send(data);
}
2
  • Gracias ya veo que me faltaba. Al menos en este caso con eso soluciono el problema. Saludos. Commented el 2 ago. 2023 a las 2:35
  • Vale. Si es solo para una llamada, con XMLHttpRequest esta bien. Pero ten en cuenta que tambien existe fetch que es mas moderno y facil de manejar, o librerias como axios. Si tu aplicacion se va a manejar con ajax frecuentemente te van a facilitar la vida Commented el 2 ago. 2023 a las 2:44

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.