Invalid argument supplied for foreach() - laravel #foreach - php

I'm trying to display product images in a Bootstrap carousel on index view (each product has many images).
PS: I already did the same thing in a previous project and it worked fine. But in this project, I don't know why it didn't work.
Here is the index() method that returns all products with their images:
public function index()
{
$salles = Salle::all();
return view('index', compact('salles'));
}
Here is the part of the index view that I'm trying to display images on:
#forelse ($salles as $salle)
<div class="col-lg-4 mb-5 mb-lg-0 p-4 text-center box-container" data-aos="fade-up" data- aos-duration="1000">
<div class="card">
<div id="carouselExampleControls{{ $salle->id }}" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($salle->images as $index => $image)
<div class="carousel-item {{ $index == 0 ?'active' : '' }}" style="height: 200px">
<img src="{{ asset('/storage/images/uploads/'.$image) }}" class="d-block w-100" alt="{{ $image }}" style="object-fit: cover">
</div>
#endforeach

It is possible same sales still does not have image. So use this code
#forelse ($salles as $salle)
#if(empty($salle->images))
#continue
#endif
<div class="col-lg-4 mb-5 mb-lg-0 p-4 text-center box-container" data-aos="fade-up" data- aos-duration="1000">
<div class="card">
<div id="carouselExampleControls{{ $salle->id }}" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($salle->images as $index => $image)
<div class="carousel-item {{ $index == 0 ?'active' : '' }}" style="height: 200px">
<img src="{{ asset('/storage/images/uploads/'.$image) }}" class="d-block w-100" alt="{{ $image }}" style="object-fit: cover">
</div>
#endforeach

Related

How to show image from database with eager loading?

I want to display multiple product image from database with eager loading, and when i tried to displaying it, console said localhost:8000/storage/ 404 not found. Any ideas how to solve this? this is my first time using eager loading & relationship on Laravel. Thank you!
Here is my controller :
public function homeProduct(){
$products = Product::with('productCategory')->get();
$images = Product::with('productImage')->get();
return view('home.index', compact('products', 'images'));
}
Product Model :
public function productImage()
{
return $this->hasMany(ProductImage::class, 'product_id', 'id');
}
Product Image Model :
public function product()
{
return $this->belongsTo(Product::class, 'id');
}
Here are the index.blade.php View :
#foreach ($products as $p)
<div class="col-lg-6 col-12">
<div class="portfolio-thumb mb-5" data-aos="fade-up">
<div id="yoreBeans" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($images as $key => $image)
<div class="carousel-item {{ $key == 0 ? 'active' : '' }}">
<a href="{{ asset('storage/'.$image->path) }}" class="image-popup">
<img src="{{ asset('storage/'.$image->path) }}" class="img-fluid portfolio-image" alt="">
</a>
</div>
#endforeach
</div>
</div>
<div class="portfolio-info">
<h3 class="text-black">{{ $p->name }}</h3>
<h4 class="text-danger">{{ $p->productCategory->name }}</h4>
</div>
</div>
</div>
#endforeach
Your method $images = Product::with('productImage')->get(); will also return Product objects with images.
What you exactly want is to eager load both realtions and then reference it at the same time:
public function homeProduct(){
$products = Product::with(['productCategory', 'productImage'])->get();
return view('home.index', compact('products'));
}
And your view like this:
#foreach ($products as $p)
<div class="col-lg-6 col-12">
<div class="portfolio-thumb mb-5" data-aos="fade-up">
<div id="yoreBeans" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<!-- // this line changed --->
#foreach ($p->productImage as $key => $image)
<div class="carousel-item {{ $key == 0 ? 'active' : '' }}">
<a href="{{ asset('storage/'.$image->path) }}" class="image-popup">
<img src="{{ asset('storage/'.$image->path) }}" class="img-fluid portfolio-image" alt="">
</a>
</div>
#endforeach
</div>
</div>
<div class="portfolio-info">
<h3 class="text-black">{{ $p->name }}</h3>
<h4 class="text-danger">{{ $p->productCategory->name }}</h4>
</div>
</div>
</div>
#endforeach

Why do I get Trying to get property 'username' of non-object while "owner_user" has information in it?

HTML Code
#foreach($posts as $post)
<div class="container card mt-2" style="width: 32rem;">
<img src="{{ asset('images')."/".$post->img_url }}" class="card-img-top" alt="img not found">
<div class="card-body">
<h5 class="card-title">{{ $post->champion }} </h5>
<p class="card-text">{{ $post->owner_user->username }}</p>
</div>
</div>
#endforeach
Laravel code
public function testpage()
{
return Posts::with(['OwnerUser','like'])->get();
}
when I just return Posts table, it has column owner_user with user information in it.
relations work, but somehow I get "Null" as a result in {{ $post->owner_user->username }} when I return it in HTML code.
because that is not a single object try
#foreach($posts as $post)
<div class="container card mt-2" style="width: 32rem;">
<img src="{{ asset('images')."/".$post->img_url }}" class="card-img-top" alt="img not found">
<div class="card-body">
<h5 class="card-title">{{ $post->champion }} </h5>
<p class="card-text">#(foreach $post->owner_user as $user){{$user->username }}#endforeach</p>
</div>
</div>
#endforeach

create view for each category - laravel

I currently print all categories in one view, with them I mark a difference between its subcategories
#foreach($tipos as $tipo)
<div class="card">
<h4 style="margin-top: 5px;">{{$tipo->tipo }}</h4>
</div>
#foreach($tipo->categories as $category)
<div style="margin-top: 20px;" class="col-lg-4 col-sm-6 mb-4">
<div class="card h-100">
<a href="{{ route('category-detail',['slug'=>$category->slug]) }}">
#if(!empty($category->image))
<img class="card-img-top" src="{{url($category->image)}}" alt="">
#else
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
#endif
</a>
<div class="card-body">
<h4 class="card-title">
{{$category->name}}
</h4>
<p class="card-text">{{$category->descripcion}}</p>
</div>
</div>
</div>
#endforeach
#endforeach
I get the names from:
categories table:
Now I need to create a view for each of them, enter it using url,
controller:
public function list($id){
$tipos = App\Tipo::findOrFail($id);
return view('list.tipos', compact('tipos'));
}
route:
Route::get('/list{id}','HomeController#list')->name('list.categories');
pivot table:
How can I print the content of each category? help pls
Modify your controller like this
Note: Change the Model Names (App\Pivote) and (App\Category) to what you have set in your code.
public function list($id){
$tipos = App\Tipo::findOrFail($id);
$pivot_data = App\Pivote::select('category_id')->where('tipo_id',$id)->get()->toArray();
$categories = App\Category::whereIn('id',$pivot_data)->get()->toArray();
return view('list.tipos', compact('tipos','categories'));
}
And modify your view something like this
<div class="card">
<h4 style="margin-top: 5px;">{{$tipos->tipo }}</h4>
</div>
#foreach($categories as $key => $category)
<div style="margin-top: 20px;" class="col-lg-4 col-sm-6 mb-4">
<div class="card h-100">
<a href="{{ route('category-detail',['slug'=>$category['slug']]) }}">
#if(!empty($category['image']))
<img class="card-img-top" src="{{asset($category['image'])}}" alt="">
#else
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
#endif
</a>
<div class="card-body">
<h4 class="card-title">
{{$category['name']}}
</h4>
<p class="card-text">{{$category['descripcion']}}</p>
</div>
</div>
#endforeach

Laravel How to skip elements if element is null in foreach loops?

I want to show latest posts in each category. If all category is not null, its OK, But if there are empty categories Trying to get property of non-object error. (I mean if category dosen't have any post)
So how can I pass thos categories post, when item returns null ?
Controller;
$categories=Category::with('posts')->latest()->get();
return view('frontend.home',compact('categories');
Blade;
#foreach($categories as $category)
<div class="col-md-3">
<div class="card text-white">
<a href="#"> <img class="card-img"
src="{{url('uploads/'.$category->posts->first()->featured_image)}}" alt="Card image">
<div class="card-img-overlay">
<h4 class="card-title">{{$category->category_name}}</h4>
</div>
</a>
</div>
</div>
#endforeach
Any advice ?
You can simply check if there are any posts in every category in the foreach and put all the html in the if statement
#foreach($categories as $category)
#if( count($category->posts) )
<div class="col-md-3">
<div class="card text-white">
<a href="#"> <img class="card-img" src="{{url('uploads/'.$category->posts->first()->featured_image)}}" alt="Card image">
<div class="card-img-overlay">
<h4 class="card-title">{{$category->category_name}}</h4>
</div>
</a>
</div>
</div>
#endif
#endforeach
to show the posts for every category...
You can simply check if there are any posts in every category in the foreach and put all the html in the if statement
#foreach($categories as $category)
#if( count($category->posts) )
#foreach($category->posts as $post)
<div class="col-md-3">
<div class="card text-white">
<a href="#"> <img class="card-img" src="{{url('uploads/'.$post->featured_image)}}" alt="Card image">
<div class="card-img-overlay">
<h4 class="card-title">{{$category->category_name}}</h4>
</div>
</a>
</div>
</div>
#endforeach
#endif
#endforeach

How to skip first item in a foreach loop in Laravel?

I am trying to fill my webpage with content based on content stored in a database. However, I would like to skip the first item; I want to start looping from the second item.
How can I achieve this?
#foreach($aboutcontent as $about)
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endforeach
As of Laravel 5.4, whenever you use foreach or for within blade files you will now have access to a $loop variable. The $loop variable provides many useful properties and methods, one of them being useful here, for skipping the first iteration. See the example below, which is a much cleaner way of achieving the same result as the other older answers here:
#foreach ($rows as $row)
#if ($loop->first) #continue #endif
{{ $row->name }}<br/>
#endforeach
Try This :
#foreach($aboutcontent as $key => $about)
#if($key > 0){
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endif;
#endforeach
Assuming that the $aboutcontents is numeric array just use the good old fashioned for loop instead of your new fangled foreach
// Notice you start at 1 and your first
// elem is 0 so... ta da... skipped
#for ($i = 1; $i < count($aboutcontents); $i++){
$about = $aboutcontents[$i]; //This is the object
//now use $about as you would
}
Note: I have not used Larvel or blades but based on the docs this should be doable
There is two way to do this:
1- if your $key is numeric you can use:
#foreach($aboutcontent as $key => $about)
#if($key == 0)
#continue
#endif
code
#endforeach
2- if a $key is not numeric
use #loop->first as a condition
You need some kind of a counter if you want to do that in blade:
<?php $count = 0;?>
#foreach
#if($count>1)
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endif
$count++
#endforeach
EDIT:
I like the answer provided by Mark Baker in the comment better
#foreach(array_slice($aboutcontent, 1) as $about)
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endforeach
Alternatively, you can just remove the first element from the array before iterating:
#php
array_shift($aboutcontent);
#endphp
#foreach($aboutcontent as $about)
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endforeach
The advantage is that you do not need any conditions to verify you are not the in the first iteration. The disadvantage is that you might need the first element within the same view, but that we don't know from your example.
Note It might make more sense to remove the first element from the array before you pass on the data to the view.
For reference, see:
http://php.net/manual/en/function.array-shift.php
https://laravel.com/docs/5.4/blade#php
Try this
#foreach($aboutcontent->slice(1) as $about)
<div class="col-md-4 text-center">
<div class="thumbnail">
<img id="" class="img-responsive" src="images/{{ $about->aboutimg }}" alt="">
<div class="caption">
<h3>{{ $about->aboutname }}</h3>
<p>{{ $about->aboutinfo }}</p>
</div>
</div>
</div>
#endforeach

Categories