Loop over and include Blade views simultaneously using @each in Laravel
Sometimes, there comes a scenario where you want to loop over a collection or array and include Blade views based on the iteration of that collection/array. You can use @foreach
and @include
for this purpose but there’s a handy way using which you can simplify this process.
The @each
directive
Laravel provides an @each
directives in which you can pass in a Blade view and a collection/array and it will handle including the view on each iteration automagically.
So, for instance, let’s say, you have an array called $books
like so.
$books = [
'Angry River',
'Harry Potter',
'Deep Work'
];
And you want to loop over this array and simultaneously render a view called resources/views/books.blade.php
with the following content…
// This will be called on each iteration of `$books`
<li>{{ $key }} - {{$book}}</li>
…inside another view on each iteration, you can do it using @each
directive like so.
<ul class="list-disc">
@each('books', $books, 'book')
</ul>
As you can tell, the @each
directive accepts three arguments.
- The first argument is the view partial (
resources/views/books.blade.php
) to render for each element in the array or collection. - The second argument is the array (
$books
) or collection you wish to iterate over. - The third argument is the variable name (
$book
inbooks.blade.php
) that will be assigned to the current iteration within the view.
The iteration key is available in the form of the $key
variable.
The example above will render the HTML something like this.
<ul class="list-disc">
<li>0 - Angry River</li>
<li>1 - Harry Potter</li>
<li>2 - Deep Work</li>
</ul>
Note: Views rendered via
@each
do not inherit the variables from the parent view. If the child view requires these variables, you should use@foreach
and@include
instead.
Default view
The @each
accepts an optional fourth argument which is a default view if in any case the collection/array is empty like so.
@each('books', $books, 'book', 'nobooks')
Here, nobooks
is the resources/views/nobooks.blade.php
Blade view which will be rendered when $books
is empty.
You can play around with this example live at Laravel Playground below.
<?php /* |------------------------------------------- | Welcome to Laravel Playground |------------------------------------------- | | Laravel Playground allows you to try out PHP and Laravel all from your browser. | You have access to all Laravel classes and an extensive list of included | Laravel packages (like Laravel DebugBar). | | You can also load your own Gists! | Simply append /gist/{YOUR-GIST-ID} to the URL. | | Do you want to see some examples? | | Multiple views: https://laravelplayground.com/#/gist/d990a2c5f23b50564561b9266252f501 | Form request validation: https://laravelplayground.com/#/gist/e5a0d029f6433e31672e55dd90429d3f | Livewire: https://laravelplayground.com/#/gist/286de510bfc0a88e697284e90ed1d7da | */ Route::get('/', function (){ return view('playground', [ 'title' => 'Laravel Playground' ]); });
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Laravel Playground</title> <link rel="stylesheet" href="https://beyondco.de/css/default.css"> </head> <body style="background: url('https://beyondco.de/img/monotone_software.png') top right no-repeat; background-size: 100% 1200px; background-position-x: calc(100% + 0px); background-position-y: -140px; "> <div class="container px-4 md:px-8 mx-auto pt-4 flex flex-col"> <div class="text-dark-blue-800 text-xl pt-4 mx-8"> @php $books = [ 'Angry River', 'Harry Potter', 'Deep Work' ]; @endphp <ul class="list-disc"> @each('books', $books, 'book', 'nobook') </ul> </div> </div> </body> </html>
<li>{{ $key }} - {{$book}}</li>
<li>No books available.</li>
Like this article?
Buy me a coffee👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.