2. Hiển thị lỗi xác thực (Displaying the validation error)

https://viblo.asia/p/tap-20-validation-laravel-GrLZDWAEKk0

Vậy, điều gì sẽ xảy ra nếu một trong các trường request không vượt qua rule validation? Như đã đề cập ở trước, Laravel sẽ tự động chuyển hướng người dùng về vị trí trước, tất cả các lỗi xác thực (validation error) sẽ được flash vào session.

Một lần nữa hãy nhớ, bạn không cần phải truyền bất kỳ dữ liệu nào vào view để có thể hiển thị các validation error. Bởi vì trước khi render view, Laravel sẽ kiểm tra xem có tồn tại validation error nào trong session không. Nếu có, một biến $errors sẽ được khởi tạo từ lớp Illuminate\Support\MessageBag cho phép ta tham chiếu tới các validation error.

Biến $errors được gửi đến view thông qua middleware Illuminate\View\Middleware\ShareErrorsFromSession, nó được cung cấp bởi nhóm middleware web. Điều này cho phép bạn có thể thoải mái giả định rằng $errors luôn xác định và có thể an toàn sử dụng.

Vậy, trong ví dụ của chúng ta, người dùng sẽ được chuyển hướng đến controller action create khi thất bại trong validation, từ đó có thể hiển thị được validation error. Bạn chỉ cần thêm đoạn code này ở phía trên đầu của nội dung blade view create_post:

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

<h1>Create new post</h1>

// ...

Quan sát đoạn code trên, mình đã sử dụng method any từ object $errors để kiểm tra xem có tồn tại validation error nào không. Nếu có tồn tại thì mình sẽ dùng vòng lặp để in tất cả các lỗi có được thông qua method all.

Bây giờ các bạn lưu lại, chạy server và thử click nút "Create" mà không nhập bất kỳ dữ liệu nào xem. Kết quả của chúng ta sẽ là:

Mặc định Laravel sẽ tự động tạo thông báo lỗi cho mỗi validation rule. Chắc bạn đang suy nghĩ là làm sao mà thay đổi mấy câu thông báo này theo ý mình được đúng không? Cứ yên tâm, mình sẽ đề cập cách làm ở phần bên dưới. Bây giờ hãy quan sát kết quả, Laravel trả về hai thông báo lỗi đó là titlebody đang để trống, lý do chúng ta chưa nhập gì cả. Tiếp theo hãy thử nhập dữ liệu như hình dưới:

Giờ hãy thử đoán xem ta có còn bị lỗi nữa không? Câu trả lời là "Có", nếu không tin bạn có thể nhấn "Create" để kiểm chứng.

Đến đây chắc các bạn cũng hình dung ra lý do vì sao rồi đúng không? Chính là do rule min:50 của trường body, nên với chuỗi My body quá ít ký tự không thể vượt qua validation.

Ngoài ra, bạn cũng có tách các thông báo lỗi này riêng cho từng input với thẻ @error trong blade template. Hãy nhìn vào ví dụ bên dưới:

<style>
    .error {
        color: red;
    }
</style>

<h1>Create new post</h1>
<form action="/post" method="POST">
    @csrf

    <div>
        <p @error('title') class="error" @enderror>
            Title
            @error('title')
                : <span>{{ $message }}</span>
            @enderror
        </p>
        <input type="text" name="title">
    </div>
    <div>
        <p @error('body') class="error" @enderror>
            Body
            @error('body')
                : <span>{{ $message }}</span>
            @enderror
        </p>
        <textarea name="body" cols="30" rows="10"></textarea>
    </div>
    <br>
    <div>
        <button type="submit">Create</button>
    </div>
</form>

Mình sử dụng cặp thẻ @error để bắt thông báo lỗi cho vị trí nào mà mình muốn, nếu tồn tại validation error thì mọi đoạn code giữa cặp thẻ sẽ được thực thi. Ngoài ra câu thông báo lỗi đầu tiên sẽ được lưu trong $message, được khai báo trong cặp thẻ @error.

Last updated