Skip to content
24 changes: 24 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use Illuminate\Http\Request;
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;

class ServiceProvider extends BaseServiceProvider
Expand All @@ -21,6 +23,7 @@ public function boot()
$this->registerRequestMacro();
$this->registerRouterMacro();
$this->registerMiddleware();
$this->shareValidationErrors();
}

protected function registerBladeDirective()
Expand Down Expand Up @@ -50,4 +53,25 @@ protected function registerMiddleware()
{
$this->app[Kernel::class]->pushMiddleware(Middleware::class);
}

protected function shareValidationErrors()
{
if (Inertia::getShared('errors')) {
return;
}

Inertia::share('errors', function () {
if (! Session::has('errors')) {
return (object) [];
}

return (object) Collection::make(Session::get('errors')->getBags())->map(function ($bag) {
return (object) Collection::make($bag->messages())->map(function ($errors) {
return $errors[0];
})->toArray();
})->pipe(function ($bags) {
return $bags->has('default') ? $bags->get('default') : $bags->toArray();
});
});
}
}
5 changes: 4 additions & 1 deletion tests/ControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ public function test_controller_returns_an_inertia_response()
$this->assertEquals([
'page' => [
'component' => 'User/Edit',
'props' => ['user' => ['name' => 'Jonathan']],
'props' => [
'user' => ['name' => 'Jonathan'],
'errors' => (object) [],
],
'url' => '',
'version' => null,
],
Expand Down
53 changes: 53 additions & 0 deletions tests/ServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

namespace Inertia\Tests;

use Closure;
use Inertia\Inertia;
use Inertia\Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ViewErrorBag;
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;

class ServiceProviderTest extends TestCase
{
Expand Down Expand Up @@ -49,4 +54,52 @@ public function test_middleware_is_registered()

$this->assertTrue($kernel->hasMiddleware(Middleware::class));
}

public function test_validation_errors_are_registered()
{
$this->assertInstanceOf(Closure::class, Inertia::getShared('errors'));
}

public function test_validation_errors_can_be_empty()
{
$errors = Inertia::getShared('errors')();

$this->assertIsObject($errors);
$this->assertEmpty(get_object_vars($errors));
}

public function test_validation_errors_are_not_registered_when_already_registered()
{
Inertia::share('errors', 'This is a validation error');

$this->assertSame('This is a validation error', Inertia::getShared('errors'));
}

public function test_validation_errors_are_returned_in_the_correct_format()
{
Session::put('errors', (new ViewErrorBag())->put('default', new MessageBag([
'name' => 'The name field is required.',
'email' => 'Not a valid email address.',
])));

$errors = Inertia::getShared('errors')();

$this->assertIsObject($errors);
$this->assertSame('The name field is required.', $errors->name);
$this->assertSame('Not a valid email address.', $errors->email);
}

public function test_validation_errors_with_named_error_bags_are_scoped()
{
Session::put('errors', (new ViewErrorBag())->put('example', new MessageBag([
'name' => 'The name field is required.',
'email' => 'Not a valid email address.',
])));

$errors = Inertia::getShared('errors')();

$this->assertIsObject($errors);
$this->assertSame('The name field is required.', $errors->example->name);
$this->assertSame('Not a valid email address.', $errors->example->email);
}
}