get value by name in relational database - laravel

by using this code in resource file
#forelse($teachers as $teacher)
{{$teacher->name}} {{$teacher->subjects}}<br>
#empty
Nothing
#endforelse
getting this value
helooo [{"id":3,"name":"Hindi","created_at":"2017-11-18 12:43:33","updated_at":"2017-11-18 12:43:33","pivot":{"teacher_id":16,"subject_id":3}}]
malik [{"id":2,"name":"English","created_at":"2017-11-18 12:43:12","updated_at":"2017-11-18 12:43:12","pivot":{"teacher_id":17,"subject_id":2}}]
hello [{"id":1,"name":"Maths","created_at":"2017-11-18 12:42:34","updated_at":"2017-11-18 12:42:34","pivot":{"teacher_id":18,"subject_id":1}}]
but by using
{{$teacher->name}} {{$teacher->subjects->name}}
getting error
Property [name] does not exist on this collection instance
how can i get just the name value in laravel

Since it's many to many, you need to iterate over subjects of each teacher:
#forelse($teachers as $teacher)
{{ $teacher->name }}<br>
#foreach ($teacher->subjects as $subject)
{{ $subject->name }}<br>
#endforeach
#empty
Nothing
#endforelse

Looks like the data that is being returned is an object in an array. Try adding a zero to select the first obj in this arr. Like this:
$teacher->subjects[0]->name
Good luck!

Related

Laravel - Trying to get property text' of non-object

This is something I've done a million times before so I'm really confused as to why I'm getting this error.
In my Controller, I fetch some results:
$modOfSubchanIDs = Auth::user()->modOf->pluck('id')->toArray();
$modmails = ModMail::whereIn('subchan_id', $modOfSubchanIDs)
->with('subchan')
->with('creator')
->with('appeal')
->orderBy('created_at', 'desc')
->paginate(10);
then in Blade, I try to output the results of the following relationship:
#foreach ($modmails as $modmail)
<div>
{{$modmail->appeal->text}}
</div>
#endforeach
Modmail Model relationship:
public function appeal()
{
return $this->belongsTo(SubchanBanAppeal::class, 'appeal_id');
}
But I get the following error:
ErrorException Trying to get property 'text' of non-object
Strange. So I try just
<div>
{{$modmail->appeal}}
</div>
which returns the following in Blade:
{"id":1,"subchan_id":8,"subchan_ban_id":1,"text":"test","denied":0,"created_by":5003,"created_at":"2021-03-26T00:07:58.000000Z","updated_at":"2021-03-26T00:07:58.000000Z"}
So now I'm really confused. Why is it returning that properly but not when I try a specific column? I also tried {{$modmail->appeal['text']}} but this returns
Trying to access array offset on value of type null
It feels like I'm missing something really basic here...
Did you do the {{ $modmail->appeal }} debug inside the loop? It is likely that most of the $modmails have an appeal, but one or two do not. If it's not the first one that is missing, your test would look right.
The optional() helper method can help in this scenario.
#foreach ($modmails as $modmail)
<div>
{{ optional($modmail->appeal)->text }}
</div>
#endforeach
https://laravel.com/docs/master/helpers#method-optional

Laravel Livewire key() expects parameter 1 to be array, integer given | nested components | loading a component inside a loop

I've been working with Laravel livewire for a while now, I've a nested components, which is product list for my site and inside that list I've another component for adding product to wishlist. As per documentation stated here , it says
"Similar to VueJs, if you render a component inside a loop, Livewire has no way of keeping track of which one is which. To remedy this, livewire offers a special "key" syntax:"
Like this:
<div>
#foreach ($users as $user)
#livewire('user-profile', $user, key($user->id))
#endforeach
</div>
Here is my code snippets from my project.
<div>
#foreach($products as $product)
<div class="product-box white-bg mb-8" data-dusk="product">
{{-- here im passing product id as param in key(), 'productList' is a static value for a variable of mount(). --}}
#livewire('desktop.wish-list-add', $product, key($product->id), 'productList')
<div class="product-content d-flex justify-content-between align-items-center p-5">
...............
#endforeach
{{ $products->links() }}
</div>
The issue is when I try to pass $product->id as param for key(), it gives error
key() expects parameter 1 to be array, integer given
But the doc clearly shows that we have to pass id as param. Has anyone faced this issue so far?
#livewire('photos.photo-wire', ['photo' => $photo], key($photo->id))
instead of
#livewire('photos.photo-wire', ['photo' => $photo, key($photo->id)])
because that will generate the error:
key() expects parameter 1 to be array, integer given
okay, I found the solution ( however it doesn't make sense to me , but it works :/ )
You have to pass other parameters for mount() like this:
#livewire('desktop.wish-list-add', 'productList', $product->id, key($product->id))
Instead of this:
#livewire('desktop.wish-list-add', $product, key($product->id), 'productList')

How to fix Laravel Old value htmlspecialchars() expects parameter 1 to be string, array given?

The "select" element is multiple select element. I am trying to get the old values and select the options selected during the form submissions.
<select class="form-control w-50" name="keywords[]" id="keywords" multiple="multiple">
</select>
I am using Select2 for this element. Data is populated from remote source.
In blade
{{ old ('keywords') }}
raises the error message that says "htmlspecialchars() expects parameter 1 to be string, array given".
What could be the problem?
The problem here is {{ var }} will try to escape var with PHP's htmlspecialchars() function, and the function accepts only strings. Here old('keywords') is returning an array.
I don't know what data you should provide to Select2, but I'm guessing #foreach will work for you:
#foreach (old('keywords') as $keyword)
<li>{{ $keyword }}</li>
#endforeach

returning multiple variables to view

So I am new to Laravel.
I know how to pass an array to a view. I am trying to alter that basic concept by passing other variable to the view as well.
Here is my route:
Route::get('sites', function()
{
$thosting = DB::table('sites')
->select(DB::raw('sum(hosting_fee) as thosting'))
->where('active', True)
->get();
$tdomain = DB::table('sites')
->select(DB::raw('sum(domain_fee) as tdomain'))
->where('active', True)
->get();
$atotal = $thosting + $tdomain;
$sites = Site::where('active', True)->orderBy('updated_at', 'DESC')->get();
return View::make('sites')
->with('sites', $sites)
->with('thosting', $thosting)
->with('tdomain', $tdomain)
->with('atotal', $atotal);
//var_dump($sites);
});
here is view sites.blade.php
#extends('layouts.master')
#section('content')
<div class="container well">
<table class="table-condensed">
<th>Annual Hosting</th><th>Annual Domain Name</th><th>Total Annual Income</th>
<tr>
<td>{{ thosting }}</td>
<td>{{ tdomain }}</td>
<td>{{ atotal }}</td>
</tr>
</table>
<h1>Hosting Accounts - Nearest to expiration </h1>
#foreach($sites as $site)
<p>{{ $site->host_renewal_date }} - {{$site->site}}</p>
#endforeach
#stop
</div>
The $site->Id etc displays a list of sites, as expected. but the 3 new variables I passed, thosting, tdomain and atotal, cause an error when I try to display them like {{ thosting }. The error is ErrorException, defined (E_unknown)
Use of undefined constant thosting - assumed 'thosting' (View: C:\Users\myname\Desktop\websites\laravel\first\app\views\sites.blade.php)
I assume I am not accessing the variables right I tried
echo thosting
that did not work either. The docs does not address returning multiple variables or not array variables. Any help from a seasoned vet is appreciated. In the end, all im trying to figure out is how to return to the view data from several DB queries.
thanks
You need to use $ in PHP variables also inside Blade views, otherwise it will try to find a constant. So just change to
<td>{{ $thosting }}</td>
<td>{{ $tdomain }}</td>
<td>{{ $atotal }}</td>
OK thanks everyone. This is what I finally got to work:
{{ $thosting[0]->thosting }}
Print_r gave me the clue that there was a property name for the object, and since i had 'sum(hosting_fee) as thosting'. I tried to point to thosting(the AS name) and it worked. After all it is an array. Great learning experience.
Would be nice if there was a way to add all these learning examples to the Laravel documentation, which only has several examples of what is possible with a lot left out.
thanks all.

Laravel templating, don't check if relation exists

I have a relationship between two models which is define by :
class Appartement extends Eloquent {
public function lang()
{
return $this->hasOne('AppartementLang')->where('language_id', '=', '2');
}
}
So nothing big.
When I try to do something like :
#foreach ($appartements as $appartement)
{{$appartement->lang->title}}<br/>
{{$appartement->lang->subtitle}}<br/>
{{link_to('/appartements/'.$appartement->link_rewrite, Lang::get('Discover'))}}<br/>
#endforeach
And that the lang does not exists, then laravel throws an error, which is pretty logical.
I wanted to know if there is some magical way which would allow me not to automate the verification that the relation exists. Basically not turn it into a big "if exists then use" for each property of the class like that :
#foreach ($appartements as $appartement)
#if($appartement->lang){{$appartement->lang->title}}<br/>#endif
#if($appartement->lang){{$appartement->lang->subtitle}}<br/>#endif
{{link_to('/appartements/'.$appartement->link_rewrite, Lang::get('Discover'))}}<br/>
#endforeach
Thanks for the advice on that.
I am sure there are lots of ways to do it (or at least try)
There is this option to check for existing and supply default if none, that I think is new in 4.1 (or at least it is new to me):
#foreach ($appartements as $appartement)
{{ $appartement->lang->title or "default if doesn't exist" }}<br/>
{{ $appartement->lang->subtitle or "default text if doesn't exist" }}<br/>
{{ link_to('/appartements/'.$appartement->link_rewrite, Lang::get('Discover')) }}<br/>
#endforeach
or you could try one of these three if statements if you don't want anything to display for that particular record depending on existance of lang...
#foreach ($appartements as $appartement)
#if ($appartement->lang)
// or maybe:
// #if ($appartement::has('lang'))
// or also maybe:
// #if ($appartement->lang->count())
{{ $appartement->lang->title or "default if doesn't exist" }}<br/>
{{ $appartement->lang->subtitle or "default text if doesn't exist" }}<br/>
{{ link_to('/appartements/'.$appartement->link_rewrite, Lang::get('Discover')) }}
<br/>
#endif
#endforeach

Resources