Min 3 elements in foreach Laravel - php

I have a collection where can be maximum 3 elements. Can be 1 element, can be 2 elements. If I have only 1 element, or 2 elements in collection I need check it and add html.
My code:
#foreach($collections->take(3)->get() as $collection)
{{ $collection->name }}
#if($collections->count() == 1)
<div>empty</div>
#endif
#if($collections->count() == 2)
<div>empty</div>
<div>empty</div>
#endif
#endforeach
I need get this result:
Collection name
empty
empty
Or If I have 2 elements in collection, I need get result:
Collection name
Collection name
empty
If I have 3 elements in collections I need get:
Collection name
Collection name
Collection name
How I can make it?

I don't see a reason why your current code wouldn't work, but you can have a go at the following approach.
Loop through the collection limited by 3 as you were, then afterwards, run a for loop - if the $collections->count() is 2, then 3-2 = 1, so you get 1 iteration of the for-loop. If the count is 3 or higher, the condition of the for loop is never true, and it doesn't print anything.
#foreach($collections->take(3)->get() as $collection)
{{ $collection->name }}
#endforeach
#for ($i = 0; $i < 3 - $collections->count(); i++)
<div>empty</div>
#endfor

Related

How to exclude items in foreach loop

I'm trying to display a specific set of references on my laravel page by iterating through an foreach loop and styling odd and even iterations differently with #class loop odd / loop even.
However I as I begin the foreach loop with an #if, only some make it into the loop while some are skipped, which messes up my odd / even (e.g. #1, #2 and #4 make it into the loop which means I have two elements styled with loop even.
How can I skip the ones that don't make it into the loop so I can display the result with alternating styling?
#foreach ($references as $reference )
#if(isset($reference['is_startpage'])
&& $reference['is_startpage'] != 1
&& isset($reference['content']['featured'])
&& $reference['content']['featured'] == 1)
<div #class([
'row py-5' => $loop->odd,
'row flex-row-reverse py-5'=> $loop->even,
])></div>
#endif
#endforeach
As you say, not every loop iteration prints the <div> element, so $loop->even and $loop->odd variables are not valid in your case for implementing that specific logic. However, there are many ways to achieve what you want. The first way that comes into my mind is using a specific counter for that, i.e.:
#php $featuredCount = 0; #endphp
#foreach ($references as $reference)
#if(
isset($reference['is_startpage'])
&& $reference['is_startpage'] != 1
&& isset($reference['content']['featured'])
&& $reference['content']['featured'] == 1
)
#php $featuredCount++; #endphp
<div #class([
'row py-5', // These two are always present, no need to conditionally rewrite them
'flex-row-reverse' => $featuredCount % 2 == 0, // 'Even' check
])></div>
#endif
#endforeach

Trying to get property 'prd_name' of non-object while trying to show results with for loop

I want to retrieve some data from the DB with for loop, So at the Controller, I have added this:
$foundOrder = Cart::select('crt_content')->whereCrtId($cart->crt_id)->latest()->first();
$foundOrder = json_decode($foundOrder->crt_content);
if ($foundOrder != null) {
foreach ($foundOrder as $key => $value) {
$prds[] = [
Product::with('uploaded')->wherePrdId($value->id)->select('*')->first(),
$value->quantity,
$value->price
];
}
} else {
$prds = [];
}
So $prds is an array and if I do {{ dd($prds) }}, I get this:
So at the Blade, I tried this:
#for($i=0;$i<=count($prds);$i++)
{{ $prds[$i]->prd_name }}
{{ $prds[$i]->prd_sale_price }}
#endfor
But it returns this error:
Trying to get property 'prd_name' of non-object
So what is wrong here ? As you can see in the picture, I'm getting all the existing products with their attributes (such as prd_id, prd_name, prd_sale_price).
You are storing Product object, quantity and price in your $prds array. And you have array inside array. Use below code
Using foreach loop
#foreach($prds as $data)
// in data 0 index will your product object,1 will be quantity and 2 will be price
{{ $data[0]->prd_name }} // prd_name from product object
{{ $data[0]->prd_sale_price }}
#endforeach
// using for loop
#for($i=0;$i<count($prds);$i++)
{{ $prds[$i][0]->prd_name }}
{{ $prds[$i][0]->prd_sale_price }}
#endfor
Your $prds is an array with each element have below structure:
[
product,
quantity,
price
];
So if you loop through it and want to get attributes of a product, you need to get it from $prds[$i][0], for example: $prds[$i][0]->prd_name.
Update: You need to loop from index 0 to count($prds) - 1:
#for($i = 0; $i <= count($prds) - 1; $i++)

syntax for conditional operator with {{ }} in laravel blade

I am trying to implement a conditional operator on a value returned from controller to create some custom view.
front.blade
#if({{count($users)}} <= 5) <!-- if total number of rows in users table is less than or equal to 5 -->
<h3> total number of rows less than or equal to 5 </h3>
#endif
controller
$users = User::all();
return view('front', [ 'users'=>$users]);
and the error is
syntax error, unexpected '<'(View: \resources\views\front.blade.php)
Tried all permutation combination of putting the condition within {{ }} or quoting the operator or the constant value 5 the error remains same. I am new to laravel and this might be a fundamental mistake in regards to laravel or php.
Just remove {{ and }}, they're not needed besides a Blade directive (#ifin this case)
You need to remove the {{ }} inside the if condition.
Like this.
#if(count($users) <= 5) <!-- if total number of rows in users table is less than or equal to 5 -->
<h3> total number of rows less than or equal to 5 </h3>
#endif
first you need to understand when you need to use curly braces.when you display your data in blade file you need to use curly braces. like
Hello, {{ $name }}.
You may construct if statements using the #if, #elseif, #else, and #endif directives. These directives function identically to their PHP counterparts:
#if (count($records) === 1)
I have one record!
#elseif (count($records) > 1)
I have multiple records!
#else
I don't have any records!
#endif
Your Solution
#if(count($users) <= 5) <!-- if total number of rows in users table is less than or equal to 5 -->
<h3> total number of rows less than or equal to 5 </h3>
#endif
for details go into laravel documentation https://laravel.com/docs/7.x/blade#if-statements
In Controller change your code like this -
$users = User::all();
return view('front', compact('users'));
Blade file code-
#if(count($users) <= 5) <!-- if total number of rows in users table is less than or equal to 5 --><h3> total number of rows less than or equal to 5 </h3>#endif

Start retrieved records at 0 MySQL Laravel

I have a forum I'm building and replies are always incrementing with their unique id's.
This means that I can have a thread and have the reply number at 550 when the thread starts, not displaying the correct reply number in relation to the thread.
Is there anyway that when I retrieve these records, I can reset them to 1 and have them increment respective to their threads?
Thanks for any help.
Here is what I have so far:
#for($i = 0; $i < $thread->replies->count(); $i++)
Post {{ $i }} of {{ $thread->replies->count() }}
#endfor
It seems to work except this is stuck in my $replies as $reply loop and it proliferates all records.
I would use a #foreach loop and the $loop variable to do the counting, See the $loop doc
#foreach($thread->replies as $post)
Post {{ $loop->iteration }} of {{ $loop->count }}
#endfor
In the case of spanning multiple pages, you should implement Pagination instead See the Pagination doc
{{ ($replies->currentPage()-1) * $replies->perPage() + $loop->index + 1 }} of {{ $replies->total() }}
Found here: Laravel - Use $loop->iteration with pagination

How to comma separate properties from a Laravel returned object

First, my apologies if the issue has been resolved. I read a lot of similar posts, but not quite the right one for my case.
I am setting up a simple project in Laravel 5.8. I want to create a simple bookstore and I need a book to have multiple authors so each title is followed by the author, or authors - if many - separated by commas and the last one by the word 'and'.
I have set up two Models, 'Author' and 'Book' and their respective tables, as well as a pivot table since they are in a relation belongsToMany. Everything works like a charm, I get my results as expected. However, I cannot get to format the results as I need. In the case of multiple authors, I always get an extra comma in the end. Since I cannot get the commas right I haven't yet tried to add the last 'and' in the case of the last author.
In the case of a single author the solution is easy, I just use a conditional.
However in the case of multiple authors, thing get complicated.
The most popular method to similar problems was the use of implode() in various similar ways. The problem with this method is since Eloquent is using its internal logic to perform the query, when I loop through 'books', there is no author column, just a reference to the pivot table. In addition, the authors' include first name and last name in different columns. So, when I try to manually create an 'implodable()' array by fetching the respective data otherwise, I get double the item size, since each name consists of the first name and theist name. And on top of that, the whole thing runs inside a double loop, making things even more complicated for me.
I am sure there is a simple way around this.
This is a sample of my blade code as of now. Of course the conditionals should be rearranged accordingly when the problem will be solved, to implement the 'and' case:
<ul>
#foreach ($books as $book)
<li>{{ $book->title }} by
#if (count($book->author) == 1)
#foreach ($book->author as $name)
{{ $name->last_name }}
{{ $name->first_name }}
#endforeach
#else
#foreach ($book->author as $name)
{{ $name->last_name }}
{{ $name->first_name }}
{{-- print a comma here if there are other names, or an 'and' if it the last one. Problem seems that it needs to be solved outside the conditional, but how? --}}
#endforeach
#endif
</li>
#endforeach
</ul>
My DB structure:
'authors': 'id', 'last_name', 'first_name','created_at', 'updated_at'
'books': 'id', 'title', 'created_at', 'updated_at'
'author_book': 'id', 'author_id', 'book_id','created_at', 'updated_at'
Expected result:
Title 1, by Author 1
Title 2, by Author 1 and 2
Title 3, by Author 1, 2 and 3
Actual Result:
Title 1, by Author 1
Title 2, by Author 1 and 2 and
Title 3, by Author 1 and 2 and 3 and
If you didn't need the "and" mechanism, then implode with comma would do the job. For "and" mechanism use below code:
<ul>
#foreach ($books as $book)
<li>{{ $book->title }} by
#for ($i = 0; $i < count($book->author); $i++)
{{ $book->author[$i]->last_name }}
{{ $book->author[$i]->first_name }}
#if ($i == count($book->author) - 2)
and
#endif
#if ($i < count($book->author) - 2)
,
#endif
#endfor
</li>
#endforeach
</ul>
added non-breaking-space &nbsp wherever necessary to not get them linked to each other
Delete #if (count($book->author) == 1), if you use foreach inside.
You can't use #else, when before you close condition with #endif.
This #else has wrong construction, use #elseif instead.
If you want check authors count and show extra value, do it inside foreach with $book->author()->count().
What relation u have for book -> author? One book can have many authors or not?
Just display implode(', ', $book->author), based on your actual result you don't need to do complicated checking if/else anymore.
#foreach ($books as $book)
<li>{{ $book->title }} by {{print implode(', ', $book->author)}}</li>
#endforeach

Categories