I've found many question realated to my problem but couldn't found an answer yet. It's about my foreach loop in my blade.
I want to print all product-names in my blade but I couln't figure out how to do that.
thats how I'm getting the products:
--- current code:
// controller
$id_array = Input::get('id');
$products= Products::whereIn('id', $id_array)->get();
$product_name = [];
foreach($products as $arr)
{
$product_name= $arr->lists('name');
}
returning $product_name gives me this as a output:
["football","cola","idontknow","freshunicorn","dummy-data"]
In my blade is just a simple:
#foreach($products as $product)
{{ $product}}
#endforeach
Error: htmlentities() expects parameter 1 to be string, array given
Thanks for your help and time.
It seems you are getting an object in an array in an array.
Like this:
array(
array(
object
)
)
It happens because you use the get() function to retrieve you model. The get() function always "wants" to retrieve multiple models. Instead you will have to use the first() function.
Like this:
foreach($id_array as $arr)
{
$want2editarray[] = Product::where('id', $arr)->first();
}
Hope it helps :)
Edit after #Wellno comment
That's probably because Product::where('id', $arr)->first(); returns null because it did not find anything.
I forgot to add a check after the retrieving of the product.
This can be done like this:
foreach($id_array as $arr)
{
// First try to get model from database
$product = Product::where('id', $arr)->first();
// If $product insert into array
if ($product) $want2editarray[] = $product;
}
Why do you use loop with IDs? You can find all products by IDs:
$products = Product::whereIn('id', $id_array)->get();
And then use $products in the blade template
#foreach($products as $product)
{{ $product->name }}
#endforeach
try to use Model/Eloquent to fetch data.
View should only display the data and not fetching directly from DB or do heavy calculations.
Related
i want to display data from my database
controller
public function generatePDF(Request $request)
{
$id = Auth::user()->id;
$name = User::select("NAME")->where("id", $id)->get();
$pdf = PDF::loadView('generatePDF', ['name'=>$name]);
return $pdf->stream('generatePDF.pdf');
}
blade
<h2>{{name}}</h2>
result
[{"NAME":"name_from_database"}]
can i display without [{"name":}], so just the value of data (name_from_database) ?
Simple use find like this
$name = User::find($id)->name;
Or direct from auth
$name = \Auth::user()->name;
To get logged in user id you can use \Auth::id()
you can use:
$user_id = User::findOrFail($id)->first();
$name=$user_id->name;
test the laravel log file:
\Log::info($name);
Use first() instead of get(), because get() will return an array and first() will return the object.
DRY Code line no.1 and no.2. simple use:
$name = auth()->user()->name;
to get the name of the currently authenticated user.
Send $name to you view is fine
$pdf = PDF::loadView('generatePDF', ['name' => $name]);
Correct your code in blade file
{{ name }} -> {{ $name }}
I hope this might help you. :)
Hello Aldi Rostiawan,
$nameGet = User::select("NAME")->where("id", $id)->get();
$nameFirst = User::select("NAME")->where("id", $id)->first();
Here in both line of code the difference is only Get and First.
Get method returns an Array of objects. So for example if the query apply on many records then the code will give you many objects in an array. Or if query will be true for only one record then also it will return an array with one object.
If you know that id is primary key of he table then only one record will be fetched then you can use First function instead if Get method.
First function always return an Object. In case if query apply on many records then also first method will return you only first record as an Object.
And it seems that you have required an Object only.
You should try this:
Controller
public function generatePDF(Request $request)
{
$id = Auth::user()->id;
$rsltUser = User::where("id", $id)->first();
$pdf = PDF::loadView('generatePDF', ['rsltUser'=>$rsltUser]);
return $pdf->stream('generatePDF.pdf');
}
blade
<h2>{{$rsltUser->name}}</h2>
use VALUE() to display name only.
in your case:
<h2>{{$rsltUser->value('name')}}</h2>
your name variable is an array containing a single object with a NAME attribute .. so to diplay that value, you should change your script to
<h2>{{name[0]['NAME']}}</h2>
I want to count each location in my Job table by using location_id in my job table with id in location table. below code, I can count result correctly but I don't know how to pass this variable to the view. Please help?
//my code
public function index(){
$location = Location::all();
$count_location = [];
foreach ($location as $locations){
$count_location = Job::where('location_id', $locations->id)->count();
}
}
Use withCount() and view() to pass location with counted jobs to the view:
public function index(){
return view('view.name', [
'locations' => Location::withCount('jobs')->get()
]);
}
In the view:
#foreach ($locations as $location)
{{ $location->name }} has {{ $location->jobs_count }} jobs
#endforeach
You can return the collection of locations to the view and then loop through each object in the collection like so:
return view('index', [
'locations'=> $locations,
]);
Then in your index.blade.php you can use something like a #foreach or #forelse loop
#foreach ($locations as $location)
{{ $location->id }}
#endfoeach
EDIT
From the looks of it you would be better off defining a relationship between locations and jobs (i.e. a "many to many" or "one to many" relationship). this would allow you to get the counts for jobs at given locations very easily like so:
$location->jobs->count()
Eloquent relationships are explained in the documentation here
https://laravel.com/docs/5.5/eloquent-relationships
It would be more efficient if construct your query to fetch the count of related models instead of looping through all the results.
Have a look at Counting Related Models in the documentations.
For example, to get the count of all jobs related to a location, you could do:
$locations = App\Location::withCount('jobs')->get();
foreach ($locations as $location) {
echo $location->jobs_count;
}
You need to adjust the code according to your models structure.
Do this
public function index(){
$locations = Location::all();
return view('index', compact('locations'));
}
In your Location model make a relationship by adding this
public function jobs(){
return $this->hasMany(Job::class);
}
In your index view do this
#foreach ($locations as $location)
{{$location->jobs->count}}
#endforeach
Please note that Job should be there in your your model
I have a Laravel 5.2 one-to-many relation and I want to return the model and put a condition to relation.
I've tried this:
$categories = Category::with(['descriptions' => function($d) use ($default_language) {
$d->where('language_id', $default_language->id);
}])->get();
It work fine, I just want something else: the relation should not be a collection or array, just a simple object. I want to do something like
$d->where('language_id', $default_language->id)->first();
, just in this case first() is not working. Any ideas?
EDIT
Actually first() is not working properly, it returns first description just for the first object returned, for others it return nothing.
Try this:
$categories = \Jobinja\CMS\Blog\Models\Category::with([
'descriptions' => function ($q) use ($defaultLanguage) {
return $q->where('language_id', $defaultLanguage->id)->take(1);
}
])
->get()
->map(function ($item) {
if ($item->descriptions->isEmpty() === false) {
$item->description = $item->descriptions->first();
}
return $item;
});
and get to description:
foreach ($categories as $category) {
$description = $category->description;
}
You can't do that but you can use first() on a collection later, for example in a view:
#foreach ($categories as $category)
{{ $category->descriptions->first()->name }}
#endforeach
I can say to use instead of first() find() and give it the language_id or $default_language->id and this will try to find in the table first the column id and assign the value. If you have different id column name give it to the find like find(['your_column_name' => '<your_value']).
If you want array to something like ->toArray(). You can test different scenarios in tinker. php artisan tinker
Here is a link to document this -> https://laravel.com/docs/5.3/eloquent#retrieving-single-models
I'm having problem with this scope in my product Model
My scope look like this:
public function scopeLessNinetyDays( $query ){
$date = new \Carbon\Carbon;
$date->subWeek(12);
return $query->where('created_at', '<', $date->toDateTimeString())->get() ;
}
I tried to loop it in category and the result is at the bottom. I need to return true or false. If the product created_at is in 12 weeks already. This is weird because it returns collection. Instead of single product.
#foreach( $category->product->take(4) as $product )
{{ dd($product->lessNinetyDays()) }}
#endforeach
If I used this code it returns single product. See Image at the bottom.
#foreach( $category->product->take(4) as $product )
{{ dd($product) }}
#endforeach
I don't know how to achieved that goal because of the results.
You are wrongly using a Local Scope. Scopes are used when selecting rows from the database, only that match the defined scope.
What you are looking for, is something like a "fake attribute" (accessor), which is probably the most Eloquent way of achieving what you are wishing for.
First, define this accessor:
public function getIsLessNinetyDaysAttribute() {
$date = (new \Carbon\Carbon)->subWeek(12);
return $this->created_at->lt($date);
}
Now, you can access this property by using:
#foreach( $category->product->take(4) as $product )
{{ dd($product->is_less_ninety_days) }}
#endforeach
This should return either true or false.
Example for using a local Scope
After defining this scope:
public function scopeLessNinetyDays( $query ){
$date = new \Carbon\Carbon;
$date->subWeek(12);
return $query->where('created_at', '<', $date->toDateTimeString())->get();
}
Now, you can chain this scope to your select query:
#foreach( $category->product->lessNinetyDays()->get() as $product )
{{ dd($product) }}
#endforeach
In this foreach loop, the only rows returned are the rows that are matching the lessNinetyDays scope.
There a multiple ways to achieve your goal, but in such cases, I always prefer an accessor.
Scope's are for query selecting. See Local Scopes
If you just add the following to the model then it should return true or false.
public function lessNinetyDays()
{
$date = new \Carbon\Carbon;
$date->subWeek(12);
return $this->created_at > $date;
}
You're using the scope incorrectly.
It's not supposed to return anything - it's only supposed to modify the query, it shouldn't return anything, especially the results of the query. Therefore you should replace
return $query->where('created_at', '<', $date->toDateTimeString())->get() ;
with
$query->where('created_at', '<', $date->toDateTimeString());
Then, if you want to fetch products that were created within last 90 days, you'll need to do the following:
$products->lessNinetyDays()->get();
See more info here: https://laravel.com/docs/5.3/eloquent#local-scopes
I created an appends attribute in Laravel Model, from the code below.
protected $appends = array('total'=>'');
And I set the returned value.
public function getTotalAttribute(){
return ProductPart::where('product_id',$this->id)->count();
}
Then I want to order records from database by using total attribute
I tried to use Product::orderBy('total','desc')->get() but it didn't work.
Does anybody has some suggestions to this?
the orderBy takes an actual database field not an appended one
try this
$products = Product::all();
$products = $products->sortBy(function($product){
return $product->total;
});
If working with attributes those are not always available instantly (e.g. for freshly created models).
As expansion on Ayobami Opeyemi's answer you should be able to use Collection's sortBy if you force the attribute to evaluate by calling its function directly:
$products = Product::all();
$products = $products->sortBy(function($product){
return $product->getTotalAttribute();
});
https://laravel.com/docs/master/collections#method-sortby
use sortBy for ASC
$collection->sortBy('field');
use sortByDesc for DESC
$collection->sortByDesc('field');
As mentioned, the proposed solution using a sortBy() callback does not work with paging.
Here is an alternative to the accepted solution:
orderByRaw()
If the appended attributes can be calculated from the fields in your query you can instead use orderByRaw(), like so:
// For example, booking percentage
$query->orderByRaw('bookings_count / total_count');
Check out a more advanced example here:
laravel orderByRaw() on the query builder
You can use the sortBy method from collections.
$products = Product::all();
$products = $products->sortBy('total');
This my example using attributes:
$collectionCenters = Supplier::where('supplier_type','=','persona_juridica')->get();
// Ordenar de forma descendente las cantidades
if ($this->unit == "kg") {
$collectionCenters = $collectionCenters->sortByDesc(function($cc) {
return $cc->qty_sold_kg;
});
}
if ($this->unit == "t") {
$collectionCenters = $collectionCenters->sortByDesc(function($cc){
return $cc->qty_sold_tons;
});
}
Then in my blade I jus call the attribute:
<td>
#if($unit == "kg")
{{ $cc->qty_sold_kg }}
#elseif($unit == "t")
{{ $cc->qty_sold_tons }}
#endif
</td>
<td>{{ $cc->details->ruc }}</td>
<td>{{ $cc->details->companyName }}</td>