Перейти к содержанию

Атрибут Json⚓︎

Атрибут #[Json] помечает действие как JSON-эндпоинт, возвращающий данные напрямую в JavaScript. Ошибки валидации вызывают отклонение промиса (promise rejection) со структурированными данными об ошибках. Это идеально подходит для действий, которые обрабатываются JavaScript, а не рендерятся в Blade.

Базовое использование⚓︎

Примените атрибут #[Json] к любому методу действия, который возвращает данные для использования в JavaScript:

resources/views/components/⚡search.blade.php
<?php

use Livewire\Attributes\Json;
use Livewire\Component;
use App\Models\Post;

new class extends Component {
    #[Json]
    public function search($query)
    {
        return Post::where('title', 'like', "%{$query}%")
            ->limit(10)
            ->get();
    }
};
<div x-data="{ query: '', posts: [] }">
    <input
        type="text"
        x-model="query"
        x-on:input.debounce="$wire.search(query).then(data => posts = data)"
    >

    <ul>
        <template x-for="post in posts">
            <li x-text="post.title"></li>
        </template>
    </ul>
</div>

Метод search() возвращает посты напрямую в Alpine, где они сохраняются в массиве posts и отрисовываются на стороне клиента.

Обработка ответов⚓︎

Методы JSON разрешаются (resolve) с возвращаемым значением в случае успеха и отклоняются (reject) при ошибке валидации:

При успехе:

let data = await $wire.search('query')
// data = [ { id: 1, title: '...' }, ...]

При ошибке валидации:

try {
    let data = await $wire.save()
} catch (e) {
    // e.status = 422
    // e.errors = { name: ['The name field is required.'] }
}

Или используя .catch():

$wire.save()
    .then(data => {
        // Обработка успеха
        console.log(data)
    })
    .catch(e => {
        if (e.status === 422) {
            // Обработка ошибок валидации
            console.log(e.errors)
        }
    })

Структура объекта ошибки⚓︎

Когда промис отклоняется, объект ошибки имеет следующую структуру:

{
    status: 422,    // Код состояния HTTP (422 для ошибок валидации)
    body: null,     // Тело ответа в сыром виде (null для ошибок валидации)
    json: null,     // Распарсенный JSON (null для ошибок валидации)
    errors: {...}   // Объект с ошибками валидации
}

Для ошибок HTTP (500 и т. д.) структура будет такой же, но с фактическими данными ответа:

{
    status: 500,
    body: '<html>...</html>',
    json: null,
    errors: null
}

Поведение⚓︎

Атрибут #[Json] автоматически применяет два типа поведения:

  1. Пропуск рендеринга — компонент не перерендеривается после завершения действия, так как ответ обрабатывается в JavaScript.
  2. Асинхронное выполнение — действие выполняется параллельно, не блокируя другие запросы.

Это поведение соответствует тому, что вы ожидаете от эндпоинта в стиле API.

Когда использовать⚓︎

Используйте #[Json], когда:

  • Создаете динамический поиск или автодополнение — получение результатов для выпадающего списка или списка подсказок.
  • Загружаете данные в JavaScript — наполнение графиков, карт или другого UI, управляемого JS.
  • Отправляете формы с обработкой в JS — когда вы хотите обрабатывать состояния успеха/ошибки в JavaScript.
  • Интегрируетесь со сторонними библиотеками — предоставление данных библиотекам, которые сами управляют своим рендерингом.

Ошибки валидации изолированы

Ошибки валидации из методов JSON возвращаются только через отклонение промиса. Они не появляются в $wire.$errors или в общем пакете ошибок компонента. Это сделано намеренно — JSON-методы самодостаточны и не влияют на отрендеренное состояние компонента.

Смотрите также⚓︎

  • Действия — Узнайте о вызове методов и получении возвращаемых значений
  • Валидация — Валидация на стороне сервера для компонентов Livewire
  • Атрибут Async — Выполнение действий параллельно без блокировки
  • Атрибут Renderless — Пропуск повторного рендеринга после действия