Skip to content

Commit c153877

Browse files
authored
Merge pull request #175 from inertiajs/lazy-props
Add lazy props feature
2 parents 0366204 + 1cae9d7 commit c153877

File tree

6 files changed

+107
-1
lines changed

6 files changed

+107
-1
lines changed

src/LazyProp.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Inertia;
4+
5+
use Illuminate\Support\Facades\App;
6+
7+
class LazyProp
8+
{
9+
protected $callback;
10+
11+
public function __construct(callable $callback)
12+
{
13+
$this->callback = $callback;
14+
}
15+
16+
public function __invoke()
17+
{
18+
return App::call($this->callback);
19+
}
20+
}

src/Response.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,15 @@ public function toResponse($request)
5454

5555
$props = ($only && $request->header('X-Inertia-Partial-Component') === $this->component)
5656
? Arr::only($this->props, $only)
57-
: $this->props;
57+
: array_filter($this->props, function ($prop) {
58+
return ! ($prop instanceof LazyProp);
59+
});
5860

5961
array_walk_recursive($props, function (&$prop) use ($request) {
62+
if ($prop instanceof LazyProp) {
63+
$prop = App::call($prop);
64+
}
65+
6066
if ($prop instanceof Closure) {
6167
$prop = App::call($prop);
6268
}

src/ResponseFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public function getVersion()
5454
return (string) $version;
5555
}
5656

57+
public function lazy(callable $callback)
58+
{
59+
return new LazyProp($callback);
60+
}
61+
5762
public function render($component, $props = [])
5863
{
5964
if ($props instanceof Arrayable) {

tests/LazyPropTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Inertia\Tests;
4+
5+
use Illuminate\Http\Request;
6+
use Inertia\LazyProp;
7+
8+
class LazyPropTest extends TestCase
9+
{
10+
public function test_can_invoke()
11+
{
12+
$lazyProp = new LazyProp(function () {
13+
return 'A lazy value';
14+
});
15+
16+
$this->assertSame('A lazy value', $lazyProp());
17+
}
18+
19+
public function test_can_resolve_bindings_when_invoked()
20+
{
21+
$lazyProp = new LazyProp(function (Request $request) {
22+
return $request;
23+
});
24+
25+
$this->assertInstanceOf(Request::class, $lazyProp());
26+
}
27+
}

tests/ResponseFactoryTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Session\Middleware\StartSession;
77
use Illuminate\Support\Facades\Route;
88
use Inertia\Inertia;
9+
use Inertia\LazyProp;
910
use Inertia\ResponseFactory;
1011
use Inertia\Tests\Stubs\ExampleMiddleware;
1112

@@ -69,4 +70,14 @@ public function test_shared_data_can_be_shared_from_anywhere()
6970
],
7071
]);
7172
}
73+
74+
public function test_can_create_lazy_prop()
75+
{
76+
$factory = new ResponseFactory();
77+
$lazyProp = $factory->lazy(function () {
78+
return 'A lazy value';
79+
});
80+
81+
$this->assertInstanceOf(LazyProp::class, $lazyProp);
82+
}
7283
}

tests/ResponseTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Illuminate\Support\Collection;
1313
use Illuminate\Support\Fluent;
1414
use Illuminate\View\View;
15+
use Inertia\LazyProp;
1516
use Inertia\Response;
1617

1718
class ResponseTest extends TestCase
@@ -182,4 +183,40 @@ public function test_xhr_partial_response()
182183
$this->assertSame('/user/123', $page->url);
183184
$this->assertSame('123', $page->version);
184185
}
186+
187+
public function test_lazy_props_are_not_included_by_default()
188+
{
189+
$request = Request::create('/users', 'GET');
190+
$request->headers->add(['X-Inertia' => 'true']);
191+
192+
$lazyProp = new LazyProp(function () {
193+
return 'A lazy value';
194+
});
195+
196+
$response = new Response('Users', ['users' => [], 'lazy' => $lazyProp], 'app', '123');
197+
$response = $response->toResponse($request);
198+
$page = $response->getData();
199+
200+
$this->assertSame([], $page->props->users);
201+
$this->assertObjectNotHasAttribute('lazy', $page->props);
202+
}
203+
204+
public function test_lazy_props_are_included_in_partial_reload()
205+
{
206+
$request = Request::create('/users', 'GET');
207+
$request->headers->add(['X-Inertia' => 'true']);
208+
$request->headers->add(['X-Inertia-Partial-Component' => 'Users']);
209+
$request->headers->add(['X-Inertia-Partial-Data' => 'lazy']);
210+
211+
$lazyProp = new LazyProp(function () {
212+
return 'A lazy value';
213+
});
214+
215+
$response = new Response('Users', ['users' => [], 'lazy' => $lazyProp], 'app', '123');
216+
$response = $response->toResponse($request);
217+
$page = $response->getData();
218+
219+
$this->assertObjectNotHasAttribute('users', $page->props);
220+
$this->assertSame('A lazy value', $page->props->lazy);
221+
}
185222
}

0 commit comments

Comments
 (0)