Trouble rendering my variables to my view - laravel

For some reason I can't seem to render these variables to my index.
Here is my code on my SellerController.
public function index()
{
$id = Auth::user()->id;
$product = Product::where('user_id', $id);
return view('seller.index', compact('product','id'));
}
and here is my code on my view
<ul>
#foreach($product as $p)
<li>
<p>{{ $p->description }}</p>
<p>{{ $p->price }}</p>
</li>
#endforeach
</ul>

You should try this:
1) You need to update your controller function like:
public function index()
{
$id = Auth::user()->id;
$product = Product::where('user_id', $id)->get();
return view('seller.index', compact('product','id'));
}
OR
2) You need to update your view file like:
<ul>
#foreach($product->get() as $p)
<li>
<p>{{ $p->description }}</p>
<p>{{ $p->price }}</p>
</li>
#endforeach
</ul>

Use get() to execute the query:
$products = Product::where('user_id', $id)->get();
And you don't need to pass $id to a view since you can just use auth()->id() directly in the view to get currently authenticated user ID.

Related

I want items to be under the category they are related to

I want to achieve this result, but I can't understand the logic of the sql implementation
here is my welcome.blade.php:
#extends('layouts/layout')
#section('content')
<div class="container-fluid">
#foreach ($categories as $category)
<h4>{{$category->category_name}}</h4>
<div class="row">
<div class="col-sm-4">
<h6>{{$category->item_name}}</h6>
</div>
</div>
#endforeach
</div>
#endsection
and my controller:
$categories = DB::table('items')
->join('categories', 'items.category_id', 'categories.id')
->select('items.item_name', 'items.item_price', 'categories.category_name', 'categories.description')
->groupBy('categories.category_name')
->get();
return view('welcome', 'categories'=> $categories]);
You can use the QueryBuilder here if you want, but I would suggest using Eloquent unless you have a particular reason to not use it.
Let's assume that you have a Category and Item model and that you've defined a relational function within the Category model back to the Item model.
class Category extends Model
{
public function items()
{
// this assumes you're using standard naming conventions
return $this->hasMany(Item::class);
}
}
Then in your Controller, you might do something like the following to obtain categories and their related items.
$categories = Category::with('items')->get();
return view('welcome', compact('categories'));
The above can be adapted when required to limit the query to a specific Category when you require it. We use the with method to eager load the related records so that we can avoid the n+1 query problem.
Finally, in your view you can iterate (loop) over the categories and loop over the related items (there could be more than one).
#forelse($categories as $category)
<h4>{{ $category->category_name }}</h4>
#forelse ($category->items as $item)
<p>{{ $item->item_name }}</p>
#empty
<p>No items</p>
#endforelse
#empty
<p>No results</p>
#endforelse
The above is purely illustrative and ideally, you would break the above into reusable components.
Since you're using Laravel, you could use Eloquent relationships:
class Category extends Model{
public function items{
return $this->hasMany(Item::class);
}
}
Then in your controller:
$categories = Category::with('items')->get();
return view('welcome', ['categories'=> $categories]);
Then in your view:
#foreach ($categories as $category)
<h4>{{$category->category_name}}</h4>
#foreach($category->items as item)
<div class="row">
<div class="col-sm-4">
<h6>{{$item->name}}</h6>
</div>
</div>
#endforeach
#endforeach
$categories = DB::table("categories")->select("id", "category_name", "description")->get();
$items = DB::table("items")->select("category_id", "item_name", "price")->get();
view('welcome',compact("categories", "items"));
/////////////////////// BLADE ///////////////////////
<div class="container-fluid">
#foreach ($categories as $category)
#foreach($items as $item)
#if($category->id === $item->category_id)
<h4>{{$category->category_name}}</h4>
<div class="row">
<div class="col-sm-4">
<h6>{{$category->item_name}}</h6>
</div>
</div>
#endif
#endforeach
#endforeach
</div>
Try this.

Laravel Categories, Subcategories and model binding

I have two tables: products and categories. Every product have specific category.
The products table has category_id.
The categories table has name and parent_id.
This is my example product: iPhone 12.
In the admin section I have category Apple and subcategory iPhone and then I put the product (iPhone 12) inside the subcategory iPhone.
In the frontend section I can successfully display the category tree unordered list and when I click on the subcategory iPhone, the product iPhone 12 displays fine but when I click on the category Apple, the product doesn't show. How can I display the data from the parent, so when I click on Apple category or iPhone subcategory to display the product in both cases?
Here's my code:
Model category
public function products()
{
return $this->hasMany('App\Models\Product');
}
public function children() {
return $this->hasMany('App\Models\Category', 'parent_id');
}
Category model
public function products()
{
return $this->hasMany('App\Models\Product');
}
ProductController
public function productCategory(Category $category) {
$categories = Category::with('children')->whereNull('parent_id')->where('status',1)->get();
$products = $category->products;
return view('products', compact('products', 'categories'));
}
Route
Route::get('/category/{category:slug}', 'App\Http\Controllers\ProductController#productCategory')->name('product.category');
Products view:
<div class="content products">
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="categories">
<ul>
#foreach($categories as $category)
<li>
{{ $category->name }}
#if($category->children)
<ul>
#foreach($category->children as $child)
<li>
{{ $child->name }}
</li>
#endforeach
</ul>
#endif
</li>
#endforeach
</ul>
</div>
</div>
<div class="col-md-9">
<div class="row">
#foreach($products as $product)
<div class="col-sm-4">
<div class="image">
<img class="img-fluid" src="{{ Storage::url($product->image) }}" />
</div>
<div class="title">
<h3>{{ $product->title }}</h3>
</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
</div>
I think you could use hasManyThrough function provided by laravel
In the category model add these functions
//retrunt only the subcategories of the category
public function subcategories()
{
return $this->hasMany(Category::class,'parent_id');
}
//return the products directly by the parent category
public function categotyProducts()
{
return $this->hasManyThrough(
Product::class,
category::class,
'parent_id',
'category_id',
);
}
for more information see the docs
Hope that works for you!
In your Product model define category relationship as below.
public function category()
{
return $this->belongsTo('App\Models\Category','category_id');
}
In your controller function define slug variable and use below query to get Products
$slug = ($category->slug)??'';
Query for products:
$products = Product::where(function($query) use ($slug){
$query->whereHas('category',function($q) use ($slug){
$q->where('name', 'like', '%' . $slug . '%');
})
->orWhereHas('category.children',function($q) use ($slug){
$q->where('name', 'like', '%' . $slug . '%');
});
})->get();

Get related products for a product by category

I'm trying to show products related to a category. But it is showing all products which are also related to other categories.
Blade:
<div class="row">
#foreach($categories as $category)
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}"
class="img-thumbnail" style="width: 270px; height: 360px;" />
<div class="block2-overlay trans-0-4">
</div>
</div>
<div class="block2-txt p-t-20">
<a href="product-detail.html" class="block2-name dis-block s-text3 p-b-5">
{{ $product->product_name }}
</a>
<span class="block2-price m-text6 p-r-5">
$75.00
</span>
</div>
</div>
</div>
#endforeach
#endforeach
</div>
Controller:
public function products(Request $request, Product $product)
{
$categories = Category::with('products')->distinct()->get();
return view('product.listing', compact('product', 'categories'));
}
Route:
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');
Edit your controller:
public function products(Request $request, Product $product)
{
$categories = $product->categories;
return view('product.listing', compact('product', 'categories'));
}
Also you should have the categories relationship method on Product Model.
public function products(Request $request, Category $category)
{
$products = Product::where('category_id',$category->id)->get();
$categories = Category:all();
return view('product.listing', compact('products','categories'));
}
Your route is
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');
//{id} it means you're getting category id from route right? so you can directly access it in controller.
Controller
//$id is from route.
public function products($id)
{
$products = Product::with('category')->where('category_id',$id)->get();
return view('product.listing', compact('products'));
}
In your blade file
#foreach($products as $product)
//here your all product which belongs to that categories.
and now if you want to access categories then may do as.
categories :- {{ $product->category->name }} //make sure it belongsTo in product
#endforech
public function products(Request $request)
{
$categories = Category::where('id',$request->id)->with('products')->get();
return view('product.listing', compact('categories'));
}
#foreach($categories as $category)
#foreach ($category as $product)
Assuming a product has one category and you have a category_id column in your products table change products method in your ProductController like below.
public function products(Request $request, Product $product)
{
$relatedProducts = Product::where('category_id', $product->category_id)
->where('id', '!=', $product->id) // ignore current product
->get();
return view('product.listing', compact('product', 'relatedProducts'));
}
Replace id in your route withproduct`. Read More about route model binding.
Route::get('/product/{product}','Admin\ProductController#products')->name('product.products');
Then in your view your you can iterate through relatedProducts
controller:
public function products(Request $request, Category $category)
{
$category->load('products');
return view('product.listing', compact('category'));
}
route:
Route::get('/product/{category}','Admin\ProductController#products')->name('product.products');
blade file:
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}" class="img-thumbnail" style="width: 270px; height: 360px;" />
</div>
</div>
</div>
#endforeach

How to output table data from controller to view?

I'm in the beginning stages of trying to make sense of Laravel and am having trouble displaying the 'illuminate collection object' passed to a blade from a controller.
My print_r is outputting "Illuminate\Support\Collection Object ( [items:protected] => Array ( ) ) 1" which I thought meant that it was seeing one item in the array (just one record in the table currently), but I'm hitting the #else statement so I'm guessing it's actually empty. I'm getting no errors, but I have not been able to display anything from $products despite $title outputting just fine.
public function shop(){
$products = DB::table('products')->get();
$data = array(
'title'=>'Shop',
'products' => $products
);
return view('pages.shop')->with($data);
}
#section('content')
<h1>{{$title}}</h1>
{{ print_r($products) }}
#if($products->count())
<ul class="list-group">
#foreach($products as $product)
<li class="list-group-item">{{$product->title}}</li>
#endforeach
</ul>
#else
<p>No products</p>
#endif
#endsection
Why is my array empty?
On your Controller:
$title = 'Shop';
$products = DB::table('products')->get();
return view('pages.shop', compact('title', 'products');
On your Blade:
I would also suggest to put your unordered list tag <ul> outside of the loop then use #forelse for a cleaner code, like so:
#section('content')
<h1>{{$title}}</h1>
<ul class="list-group">
#forelse($products as $product)
<li class="list-group-item">{{$product->title}}</li>
#empty
<li class="list-group-item">No products</li>
#endforelse
</ul>
#endsection
Try this..........
public function shop()
{
$products = DB::table('products')->get();
$title = "Shop";
return view('pages.shop', compact('products', 'title'));
}
#section('content')
<h1>{{ isset($title) ? $title : '-' }}</h1>
#if($products->count())
<ul class="list-group">
#foreach($products as $product)
<li class="list-group-item">{{ isset($product->title) ? $product->title : '-' }}</li>
#endforeach
</ul>
#else
<p>No products</p>
#endif
#endsection
You can display the data by first passing it as an array to the view
return view('pages.shop')->with('data', $data);
then in the blade
#section('content')
<h1>{{$data['title']}}</h1>
#if(count($data['products']))
<ul class="list-group">
#foreach($data['products'] as $product)
<li class="list-group-item">{{$product->title}}</li>
#endforeach
</ul>
#else
<p>No products</p>
#endif
#endsection
Pass both $products and $title to the view, I prefer to use compact feels cleaner.
$title = 'shop';
$products = DB::table('products')->get();
return view('pages.shop', compact('title', 'products');
Then in your view you can reference them directly. As you are doing now.
#section('content')
<h1>{{$title}}</h1>
#if($products->count())
<ul class="list-group">
#foreach($products as $product)
<li class="list-group-item">{{$product->title}}</li>
#endforeach
</ul>
#else
<p>No products</p>
#endif
#endsection
In your controller
$title = 'shop';
$products = DB::table('products')->get();
return view('pages.shop', compact('title', 'products');
OR
$products = DB::table('products')->get();
$data = array(
'title'=>'Shop',
'products' => $products
);
return view('pages.shop')->with('data',$data);
In your Blade
#section('content')
<h1>{{$title}}</h1>
#if(count($products))
<ul class="list-group">
#foreach($products as $product)
<li class="list-group-item">{{$product->title}}</li>
#endforeach
</ul>
#else
<p>No products</p>
#endif
#endsection

Laravel filter results with dropdown menu

I am showing abstracts from my database and I want to filter them using drop-down menu.
I have already created the drop-down menu with the categories which are Medicine and Nursing
my view which includes the drop-down menu
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-
toggle="dropdown" value="">Show all</button>
<ul class="dropdown-menu" role="menu">
#foreach ($schools as $school)
<li value="{{ $school->id }}">{{ $school->School_Type }}</li>
#endforeach
</ul>
</div>
My controller
public function index(Request $request)
{
$schools = School::all();
$items = $request->items ?? 5; // get the pagination number or a default
$abstracts = Project::orderBy('A_ID','asc')->paginate($items);
return view ('Abstracts.index')->with ('abstracts', $abstracts)
->withItems($items)
->with('schools',$schools);
}
can someone guide how to route it properly
I'd do it like this:
public function index(Request $request)
{
$schools = School::all();
$items = $request->items ?? 5; // get the pagination number or a default
$abstracts = Project::orderBy('A_ID','asc')->paginate($items);
return view ('Abstracts.index')->with([
'abstracts' => $abstracts,
'items' => $items,
'schools' => $schools
]);
}
And in your view, you can confirm it like:
#foreach ($schools as $school)
{{ $school }}
#endforeach

Resources