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 (
$bookinbooks.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
@eachdo not inherit the variables from the parent view. If the child view requires these variables, you should use@foreachand@includeinstead.
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>
👋 Hi there! This is Amit, again. I write articles about all things web development. If you enjoy my work (the articles, the open-source projects, my general demeanour... anything really), consider leaving a tip & supporting the site. Your support is incredibly appreciated!