Laravel - Trying to get property 'name' of non-object - laravel

Im making a view that shows the users and the companies they work for.
In my User model i return the view like this:
return view('users.index', ['users' => $model->all()]);
The model $model->all() is my User model.
Then in my index.blade file i loop through the data like this:
#foreach ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>
{{ $user->email }}
</td>
<td>{{ $user->created_at->format('d/m/Y H:i') }}</td>
<td>{{ $user->company->name }}</td>
<td class="text-right">
<div class="dropdown">
<a class="btn btn-sm btn-icon-only text-light" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
#if ($user->id != auth()->id())
<form action="{{ route('user.destroy', $user) }}" method="post">
#csrf
#method('delete')
<a class="dropdown-item" href="{{ route('user.edit', $user) }}">{{ __('Edit') }}</a>
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this user?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
#else
<a class="dropdown-item" href="{{ route('profile.edit') }}">{{ __('Edit') }}</a>
#endif
</div>
</div>
</td>
</tr>
#endforeach
But when i try to show $user->company->name i get the following error:
Trying to get property 'name' of non-object
I tried debugging by using dd($user->company) and it showed all the company information of the company connected to the user. Then i tried dd($user->company->name) and it showed the company name.
I dont understand why i cant just show $user-company->name without getting the error but when i dd($user->company->name) it shows the company name.
Can someone point me in the right direction.

It probably shows an error because one of your users doesn't have a company. The first one of your loop has one, that's why when you dd($user->company), you see a company. But it doesn't mean the second or third has one. You can do a if statement in order to catch any null company. Something like
if($user->company == null){
dd($user);
}
Alternatively, you can just do dd($users->pluck('company','id'));, which will show you a collection with the user id as key and related company (or null) as value.

You can use optional() helper to solve this. There are users who don't have companies. SO you can display them like this optional($user->company)->name and you will not get an error if a user does not have a company

If you are trying to get relationship object value might be chances are there you will get this type of error. Due to there is some user who doesn't have company detail.
Just try below code.
{{ #$user->company->name }}

Related

Laravel 7.x with Nova Can't use menu from optimistdigital/nova-menu-builder

I am new to Laravel Nova ... I just installed optimistdigital/nova-menu-builder in order to generate menus in a more efficient way then whats generated by nova. My menu structure is very complex and needs more control. Anyway, I installed the package and created a menu. I am at the point where I would like to load it in the sidebar but can't figure out how that works ...
in the navigation.blade.php file I added:
#menu("admin")
Where admin is supposed to be the menu slug
After a refresh, nothing happened. So I tried something more basic. I removed the #menu and added "hello world" instead. It did not appear ... So I ran the following commands:
php artisan config:clear
php artisan cache:clear
php artisan nova:publish
All 3 were executed without any errors. But the sidebar still did not show my hello world.
So my question is the following. How can I reflect my changes in the blade views? And is #menu("") the right way to use the optimistdigital/nova-menu-builder package? The documentation seems to be missing the part on how to use the menus you create... Thx in advance!
Here's my layout page
<router-link exact tag="h3"
:to="{
name: 'dashboard.custom',
params: {
name: 'main'
}
}"
class="cursor-pointer flex items-center font-normal dim text-white mb-8 text-base no-underline">
<svg>[Long SVG string]</svg>
<span class="text-white sidebar-label">{{ __('Dashboard') }}</span>
</router-link>
hello world
#menu("admin")
#if (\Laravel\Nova\Nova::availableDashboards(request()))
<ul class="list-reset mb-8">
#foreach (\Laravel\Nova\Nova::availableDashboards(request()) as $dashboard)
<li class="leading-wide mb-4 ml-8 text-sm">
<router-link :to='{
name: "dashboard.custom",
params: {
name: "{{ $dashboard::uriKey() }}",
},
query: #json($dashboard->meta()),
}'
exact
class="text-white no-underline dim">
{{ $dashboard::label() }}
</router-link>
</li>
#endforeach
</ul>
#endif
Thx to leek, I was able to find how to retrieve the menus and build on that.
So my first problem was that I was editing the wrong file. You need to do the following first:
copy the file in nova/resources/views/layout.blade.php and put it in
/resources/views/vendor/nova.
After doing this your changes will reflect correctly. I moved all the files in the nova view folder while I was at it.
In side the newly created /resources/views/vendor/nova/layout.blade.php file replace this code:
#foreach (\Laravel\Nova\Nova::availableTools(request()) as $tool)
{!! $tool->renderNavigation() !!}
#endforeach
with this code:
#php
$menus = [
nova_get_menu('admin'),
];
#endphp
<section style="width: 100%; position: absolute; top: 60px;">
<ul class="sidebar-menu">
<li class="sidebar-header">MAIN NAVIGATION</li>
<li>
<a href="/nova">
<i class="fa fa-dashboard"></i> <span>Dashboard</span></i>
</a>
</li>
#foreach ($menus as $menu)
#continue(is_null($menu))
<li>
<a href="">
<i class="fa fa-dashboard"></i> <span>{{ $menu['name'] }}</span> #if ($menu['menuItems'])<i class="fa fa-angle-left pull-right"></i> #endif
</a>
#if ($menu['menuItems'])
<ul class="sidebar-submenu">
#foreach (($menu['menuItems'] ?? []) as $item)
<li>
#if ($item['type'] === 'text')
{{ $item['name'] }}
#else
<a href="{{ $item['value'] }}"
target="{{ $item['target'] }}"
#if ($item['target'] === '_blank') rel="noopener" #endif><i class="fa fa-circle-o"></i> {{ $item['name'] }}</a>
#endif
</li>
#endforeach
</ul>
#endif
</li>
#endforeach
<li>
<a href="/nova/logout">
<i class="fa fa-sign-out"></i> <span>Logout</span></i>
</a>
</li>
</ul>
</section>
Replace "admin" with the slug of your menu
You can change the HTML to what ever you want.
I used https://www.jqueryscript.net/menu/Stylish-Multi-level-Sidebar-Menu-Plugin-With-jQuery-sidebar-menu-js.html
And the result is:
You can add more then one menu like this if you need to
#php
$menus = [
nova_get_menu('admin'),
nova_get_menu('user'),
nova_get_menu('pages'),
nova_get_menu('configuration'),
nova_get_menu('store'),
];
#endphp
The foreach loop will add them all to your page in the order you put them in the $menus array.
Good luck!
Quote from this issue on GitHub:
[nova_get_menu()] only returns a PHP array. You have to handle creating the HTML yourself.
As of version 2.3.7, you will need to use this function yourself to generate your own menu HTML:
$menuJson = nova_get_menu('admin')
// Returns:
// [
// 'id',
// 'name',
// 'slug',
// 'locale',
// 'menuItems' => []
// ]

Laravel assigning the ID to a Zurb Foundation modal

I'm currently making a CMS, for a local charity (free of charge) and I'm using Laravel 5.6 along with Zurb foundation 6.4. It's my first time using Laravel, but I've really enjoyed it and I've almost finished.
However, I have a couple of little niggles, that I need to fix, before I deploy it and a little guidance would help, a lot. I'm stuck with assigning a dynamic ID to my modal, to update. My controller, route and model are fine. I can update the first record, from the table, with the modal and that works as expected.
The problem is, it is always the first record that is shown, irrespective of whether I click the trigger, on an unrelated row. I've tried to pass the category_id in, using Blade, but that doesn't work, I either get the same result or an error. I can see what the problem is, but I don't know how to fix it. I think I need some jQuery and/or Ajax and I have tried, to no avail (I'm rubbish with JS).
As I said, my MVC is sound, I can update the first row and all I need is to be able to dynamically assign the category_id to the data-open attribute. I'll post my code, below and thanks for taking time to read this.
#foreach ($categories as $category)
<tr>
<td>{{ $category->name }}</td>
<td>{{ $category->posts->count() }}</td>
<td align="center"><a data-open="editModal"><i class="fas fa-edit fa-lg" style="color: green"></i></a></td>
<td align="center">
<i class="fas fa-trash-alt fa-lg" style="color: red"></i>
</td>
</tr>
<div class="reveal" id="editModal" data-reveal>
<h3>Edit: {{ $category->name }}</h3>
<form action="{{ route('category.update', ['id' => $category->id]) }}" method="post">
{{ csrf_field() }}
<label for="name">Category Name</label>
<input type="text" name="name" value="{{ $category->name }}">
<button class="button expanded success fullRadiusButton" type="submit">Update Category</button>
<i class="fas fa-window-close"></i>
</form>
</div>
#endforeach
An element is unique in the document based on the id property but you're using the same id (editModal) multiple times. You're instructing the Reveal Modal library to open the modal with an id of editModal so it finds the first one (which it expects to be the only one) and opens it. An id should only ever appear once in a document, or you'll experience unexpected behaviour like this.
id - unique to a single element
class - not unique to an element
You can fix this by giving each edit modal a unique id, something like this:
<div class="reveal" id="editModal_{{ $category->id }}" data-reveal>
Then in your trigger reference that unique id:
<a data-open="editModal_{{ $category->id }}">

Property [articles] does not exist on this collection instance. laravel 5.4

help or assist as it does not turn out to make sorting on categories, I can not understand as to solve this problem.
I recently study laravel.
Controller: class ArticlesController
public function showAll ($category_id)
{
$categories = Category::where('name', $category_id)->get();
return view('categories')->with(compact('categories', 'articles'));
}
This view from which I want to go into categories. site.blade.php
#foreach($categories as $category)
<li><a class="nav-link text-white" href={{route('articlesShow', ['id'=>$category->id]) }}">{{ $category->name }}</a></li>
#endforeach
Route:
Route::get('/categories/{category_id}', 'ArticlesController#showAll')->name('articlesShow');
Model: Category
public function articles()
{
return $this->hasMany(Article::class, 'category_id');
}
Representation in which does not get to get: categories.blade.php
#foreach($categories->articles as $article)
<div class="col-6 col-lg-4"> <!--Post -->
<img src="{{ asset('upload/image/1.jpg') }}" width="255" alt="..." class="rounded img_size">
<h4> {{ $article->title }}</h4>
<h6>Category: {{ $article->category->name }}</h6>
<h6>Author: {{ $article->author }}</h6>
<p>{{ $article->text }} </p>
<p><a class="btn btn-secondary" href="{{ route('articleShow', ['id' =>$article->id]) }}"> More »</a></p>
</div><!--EndPost-->
#endforeach
$categories is an array that contains categories, and the articles property belongs to a category, therefore you have to loop the categories before you can access the articles.
try this:
#foreach($categories as $category)
#foreach($category->articles as $article)
<div class="col-6 col-lg-4"> <!--Post -->
<img src="{{ asset('upload/image/1.jpg') }}" width="255" alt="..." class="rounded img_size">
<h4> {{ $article->title }}</h4>
<h6>Category: {{ $article->category->name }}</h6>
<h6>Author: {{ $article->author }}</h6>
<p>{{ $article->text }} </p>
<p><a class="btn btn-secondary" href="{{ route('articleShow', ['id' =>$article->id]) }}"> More »</a></p>
</div><!--EndPost-->
#endforeach
#endforeach
First of all: use eager loading.
Assuming, your ArticlesController#showAll method should display all articles for a given category id, your query should look like this
public function showAll ($category_id)
{
$categoryArticles = Category::with('articles')->where('id', $category_id)->get();
return view('categories')->with('categoryArticles', $categoryArticles);
}
Then to display all articles for the given category (assuming an article has only one category), this could be one way:
#foreach($categoryArticles->articles as $article)
<div class="col-6 col-lg-4"> <!--Post -->
<img src="{{ asset('upload/image/1.jpg') }}" width="255" alt="..." class="rounded img_size">
<h4> {{ $article->title }}</h4>
<h6>Category: {{ $categoryArticles->name }}</h6>
<h6>Author: {{ $article->author }}</h6>
<p>{{ $article->text }} </p>
<p><a class="btn btn-secondary" href="{{ route('articleShow', ['id' =>$article->id]) }}"> More »</a></p>
</div><!--EndPost-->
#endforeach

Laravel 5.4, user cannot see dashboard if they don't own anything

The problem is, is that when I sign a new user up (in my application a 'charity owner'), they are redirected to their dashboard.
On the dashboard, displays the all the charities that the user owns and any donations made to them in another table.
However, because the user has not added their charity to the database yet I am getting undefined variables.
#forelse($ownedCharities as $owned)
<td> {{ $owned->name }} </td>
<td> Not Available </td>
<td> <p id="desc"> {{ $owned->description }} </p> <p style="color: #000;" class="seeMore"> See more... </p> </td>
<a href="#"> <button class="btn btn-danger btnPopover"
data-toggle="popover" data-placement="top"> Delete </button> </a> </td>
<td> <button class="btn btn-warning"> Edit </button> </td>
</tr>
#empty
<p> No charities owned </p>
#endforelse
I am using Blade's #forelse
You can use php functions in blade like to see if they are or not defined or has some value
#isset($records)
// $records is defined and is not null
#endisset
#empty($records)
// $records is "empty"...
#endempty
You can use Null coalescing operator which is introduces in PHP 7
$records ?? ""

Foreach loop of Eloquent relationship in Laravel view then changes any further results below it

I have a Eloquent relationship defined in the a Model.
In my Controller I am getting some profiles like so:
$profiles = $this->profileRepo->paginate('10');
In my view I make use of a relationship in the Profile model which gets the related images and user this in the foreach loop.
But then after this I try to get the Profile->nick_name and it won't work. I did a dd() and it shows the Model has now changed from Profile to the Image..
#foreach($profiles as $row)
<div>
#foreach($row->image->where('profile_picture', '1') as $row)
<a href="$row->file">
<i class="fa fa-plus"></i>
</a>
#endforeach
</div>
<div>
//If this was ^^^Above^^^ the foreach() loop then it works fine :)
<h3>{{ $row->nick_name }}</h3>
<p>{{ $row->about }}</p>
</div>
#endforeach
Not sure why that happens or how to prevent it.
Your inner foreach loop overrides the $row variable.
Use a different variable in your inner loop:
#foreach($profiles as $profile)
<div>
#foreach($profile->image->where('profile_picture', '1') as $image)
<a href="{{ $image->file }}">
<i class="fa fa-plus"></i>
</a>
#endforeach
</div>
<div>
<h3>{{ $profile->nick_name }}</h3>
<p>{{ $profile->about }}</p>
</div>
#endforeach

Resources