Laravel blade "undefined variable" error when using route() - php

As a project I am building a stackoverflow like forum. On the page on which a single question is shown I want the user to be able to click on the questioner's name and be forwarded to the respective user profile page. I am able to get the name from the database with {{ $question->user->name }}. The problem occurs when adding the part!
Also, the profile pages work. I can access them and the url then says for example: ../profile/1.
This is the route in the web.php file:
Route::get('/profile/{user}', 'PageController#profile')->name('profile');
This is the PageController part:
public function profile($id)
{
$user = User::with(['questions', 'answers', 'answers.question'])->find($id);
return view('profile')->with('user', $user);
}
This is the code from the show.blade View question page which does not work:
<p>
Submitted by {{ $question->user->name }}
</p>
The error message I get is Undefined variable: user.
Which surprises me because forwarding on the profile page to a specific question works with this blade code:
View Question
The respective route in the web.php file:
Route::resource('questions', 'QuestionController');
And QuestionController:
public function show($id)
{
$question = Question::findOrFail($id);
return view('questions.show')->with('question', $question);
}
I thought I defined the variable $user in the PageController like I defined $question in the QuestionController?

I can see you are using Eloquent models with relations. If you want to display the user id on the question, you can use the relation between the Question and User to find the id of the posting user.
Submitted by {{ $question->user->name }}
^^^^^^^^^

//just change your like this way
public function profile($id)
{
$user = User::with(['questions', 'answers', 'answers.question'])->find($id);
return view('profile',compact('user));
}

Related

Laravel Model Relationships show Admin details from post

I'm creating a small social media where admin can posts to user's dashboard but having trouble with showing the admin details like profile picture to the posts
this is the error i got
Trying to get property 'profile_image' of non-object
Check my code
Post.php // my post model
public function admin()
{
return $this->belongsTo('App\Admin');
}
Admin.php // my admin model
public function post()
{
return $this->hasMany('App\Post');
}
now on my user dashboard i would try to access my admin details using this code {{ $post->admin->profile_image }}
You get that error because $post->admin is null You must be check $post->admin empty or not
{{ $post->admin ? $post->admin->profile_image : ''}}

Laravel get record from database in blade view

I would like to known how to get data from database in blade like from User table:
{{ Auth::user()->name }}
I have table user_settings
I would like to get record from this table by logged user id like this:
{{ UserSettings::user()->my_field }}
How can I do that?
Try this on your blade view
{{ \App\UserSettings::where('user_id',Auth::user()->id)->first()->my_field }}
In default, model file is inside App folder.
Such direct access to database table is not preferred though, you can return this as a variable from controller function like,
$field = \App\UserSettings::where('user_id',Auth::user()->id)->first()->my_field;
return view('view_name',comapact('field'));
and use in blade like
{{$field}}
Another good way is posted by Orkhan in another answer using eloquent relationship.
Hope you understand.
You need to retrieve the UserSettings associated to the authenticated user:
UserSettings::where('user_id', Auth::id())->first()->my_field
You can defined a method named current() to return that for you.
class UserSettings extends Model
{
public static function current()
{
return UserSettings::where('user_id', Auth::id())->first()
}
}
Then use:
UserSettings::current()
On the other had it would better to use one-to-one relationship on user model:
class User extends Model
{
public function settings()
{
return $this->hasOne('App\UserSettings');
}
}
Then use:
Auth::user()->settings->my_field

Delete data from the database with Laravel 5.4

I am sort of new to the Laravel framework and I am building just a simple blog. I can create a blog, show a blog and show a overview of all blogs. Now I would like to delete a blog. So, I have created a delete button in my view with a route link which will pass also the id of the article. Then, in my routes file I specify a delete request and a controller method. In the method I find the id and try to delete the row with the id I specified in the route/view.
This doesn't work. Instead of activate the destroy/delete method it shows the article instead of deleting it and activates the show method instead of the delete method. Can somebody help me out, What do I wrong?
View.blade.php
<a href="{{route('nieuws.destroy', ['id' => $blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
<i class="fa fa-trash"></i>
</a>
Route
Route::group(['middleware' => 'auth'], function () {
Route::get('/aanvragen', 'aanvragenController#index')->name('aanvragen.index');
Route::get('/logout' , 'Auth\LoginController#logout')->name('logout');
Route::get('/nieuws/toevoegen', 'blogController#create')->name('blogs.add');
Route::post('/nieuws/store', 'blogController#store')->name('nieuws.store');
Route::delete('/nieuws/{id}', 'blogController#destroy')->name('nieuws.destroy');
});
Route::get('/nieuws', 'blogController#index')->name('blogs.index');
Route::get('/nieuws/{blog}', 'blogController#show')->name('blogs.show');
Controller methods
Delete/Destroy
public function destroy($id) {
$blog = Blog::find($id);
$blog->delete();
return redirect('/nieuws');
}
Show
public function show(Blog $blog) {
dd('show');
return view('blogs.show', compact('blog'));
}
A delete() route requires you to POST your data.
HTML forms only supports GET and POST, other methods like DELETE, PUT, etc are not supported, that's why Laravel uses the _method to spoof methods which are not supported by HTML forms.
You do not want use GET in these cases, since someone can send a user the url (http://yoursite.com/blog/delete/1) in an IM or via email. The user clicks and the blog is gone.
Define your route as it would be when using resource controllers, so:
Route::delete('/nieuws/{id}', 'blogController#destroy')->name('nieuws.destroy');
And either use a form with the delete method:
// apply some inline form styles
<form method="POST" action="{{ route('nieuws.destroy', [$blog->id]) }}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit">Delete</button>
</form>
Or do some javascript magic as the link SR_ posted in his comment on your OP.
One more thing, add some sort of validation in your destroy action. Right now when you provide a non-existing id or something else, you will get a 500 error, instead you want to have a 404.
public function destroy($id)
{
$blog = Blog::findOrFail($id);
$blog->delete();
return redirect('/nieuws');
}
I think you need to update your destroy function like:
public function destroy($id) {
$blog = DB::table('blog')->where('id',$id)->delete();
return redirect('/nieuws');
}
And update your view code like:
<a href="{{route('nieuws.destroy', [$blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
<i class="fa fa-trash"></i>
</a>
Hope this work for you!
I'm also new to Laravel but I made it work through this way:
(I use 'Article' as the model's name and the resource "method" in the route stands for a bunch of useful routes including the route you wrote)
Controller:
public function destroy($id){
Article::find($id)->delete();
//$article = Article::find($id);
return redirect()->back()->withErrors('Successfully deleted!');
}
Route:
Route::resource('article','ArticleController');
However, I think the problem lies in the default definition of database's name of your model. Laravel will assume that you have a database named blogs since you have a model named "blog". Are you having the database's name right?
To use DELETE HTTP Verb, your form should consists of the POST method and settings the method_field('DELETE')
Example:
<form method="POST" action="{{ route('xxx.destroy', $xxx->id) }}">
{{ csrf_field }}
{{ method_field('DELETE') }}
</form>

Laravel Error: Property [id] does not exist on this collection instance. Yet it works on the local server

As mentioned in the title I get the error "Property [id] does not exist on this collection instance." Only when I run the code online here are my relevant codes.
1-EmployeeController (browser tells me that the error is here the second line)
public function show(Employee $employee)
{
$employee = Employee::find ($employee);
$edocument = EDocument::where ('employee_id',$employee->id)->first();
return view ('employee.show')->withEmployee($employee)->withEdocument($edocument);
}
2-show.blade.php
<div class="jumbotron">
<h1>{{$employee->name}} ({{$employee->position}})</h1>
#if (isset($edocument))
Go To Employee Database Page
#else
<p class="lead bg-danger">Employee documents are not uploaded</p>
#endif
Create Employee Contract
if anyone can explain to me this error in more details that would be great also. thanks
ps.. this is my first laravel project (;
You use route model binding in your controller method to get the Employee model. But you also run a find, which would fail since you're passing the model instead of the id. Do as one of the codes shown below and don't mix them.
Do this if you want to use route model binding.
public function show(Employee $employee)
{
$edocument = EDocument::where ('employee_id', $employee->id)->first();
return view ('employee.show')->with(compact('employee', 'edocument'));
}
Do this if you want to pass the employee id and fetch the model in controller.
public function show($employee)
{
$employee = Employee::find($employee);
$edocument = EDocument::where ('employee_id', $employee->id)->first();
return view ('employee.show')->with(compact('employee', 'edocument'));
}
Maybe this can help you. Why don't you pass the information in the controller using -
return view('employee.show', ['employee' => $employee, 'edocument'=>$edocument]);
It worked for me. (Do not have to change anything in the show.blade .php)

Access attribute of a 'hasOne' related object

In my User class I have this function:
public function profile() {
return $this->hasOne('App\Profile');
}
In the controller I used $users = User::all() to get all the users and then pass it to the view using with('users', $users)
In the view where I want to display all of my users profiles I used foreach loop to get to each user data like:
#foreach($users as $user)
<div> {{ $user->profile->some_prfiles_table_column_name }} </div>
But i got an error, So I had to access it using square brackets like this:
{{ $user->profile['some_profiles_table_column_name'] }}
And in another view, where i retrieved only one user by id User::find($id) then i can access the user profile attributes normally as an object NOT array, Like:
{{ $user->profile->some_profiles_table_column_name }}
What i want to understand is Why i'm getting an array instead of an object? Is there is something wrong or this is normal in laravel?
Thanks in advance
You're not getting an array. Eloquent Models implement PHP's ArrayAccess interface, which allows you to access the data as if it were an array.
The problem you're having is that one of your users does not have an associated profile. When that happens, $user->profile will be null. If you attempt to access an object property on null, you'll get a "Trying to get property of non-object" error. However, if you attempt to access an array property of null, it'll just return null without throwing an error, which is why your loop appears to work as an array.
Illustrated with code:
foreach ($users as $user) {
// This will throw an error when a user does not have a profile.
var_export($user->profile->some_profiles_table_column_name);
// This will just output NULL when a user does not have a profile.
var_export($user->profile['some_profiles_table_column_name'];
}
So, presumably, you'll want to handle the situation in your code when the user does not have a profile:
#foreach($users as $user)
<div> {{ $user->profile ? $user->profile->some_profiles_table_column_name : 'No Profile' }} </div>
#endforeach

Categories