I have the following snippet of code that should return the contents of a post.
My View:
#foreach($posts as $post)
<h2 class="post-title"> {{$post->title}} </h2>
<p> {{ $post->content_posts()->first()}} </p>
#endforeach
This return the ENTIRE object,
As soon as you only want the content (or any other attribute) part of the object it throws "Trying to get a property of a non-object" error
The View that has the error:
#foreach($posts as $post)
<h2 class="post-title"> {{$post->title}} </h2>
<p> {{ $post->content_posts()->first()->content}} </p>
#endforeach
The Controller looks as follows:
public function getAllPost(){
$posts = Post::all();
return View::make('posts.allposts', ['posts' => $posts]);}
The Model relationship are as follows:
This is the Post model:
public function content_posts(){
return $this-> hasMany('ContentPost');}
The ContentPost model:
public function post(){
return $this-> belongsTo('Post');}
Is there a mistake somewhere in my Model, Controller or in the View?
Try using;
$post->content_posts()->first()['content']
Make sure to check for the data $post->content_posts()->first() before you display what you want to prevent this error from occurring again.
Related
I'm new to laravel. I want to access the products belongs to the category. There is One-to-Many relation between them. To get this data I created a function inside ProductsController named getCtgProducts() to do just that.
I know it a bad practice to query a database straight from views, hence I am writing the database query in the controller and trying to access it inside the blade.
Can someone tell me what I'm doing wrong?
What is the proper way to access the controller function inside the blade view? I'm using Laravel Framework v9.7.0
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It is working. Showing the correct ctgs names
<div class=container>
#if (isset($products))
#foreach ({{ App\Http\Controllers\ProductsController::getCtgProducts($ctg->id) }} as $product)
<h1> $product->name </h1>
#endforeach
#endif
</div>
#endforeach
ProductsController class
<?php
namespace App\Http\Controllers;
use App\Models\Ctg;
use App\Models\Product;
class ProductsController extends Controller
{
public function index(Request $request)
{
$products = Product::all();
$ctgs = Ctg::all();
return view('ui\welcome', compact('products', 'ctgs'));
}
public static function getCtgProducts(){
$ctgProducts = DB::table('products')->where('ctg_id', $ctgId);
return $ctgProducts;
}
}
Calling controller from blade is bad practice
move your getCtgProducts() method logic to Category Model:
public function getCtgProducts(){
$ctgProducts = DB::table('products')
->where('ctg_id', $this->id)->get();
return $ctgProducts;
}
Blade file:
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It is working. Showing the correct ctgs names
<div class=container>
#foreach ($ctg->getCtgProducts() as $product)
<h1> $product->name </h1>
#endforeach
</div>
#endforeach
Better way:
Since there's one-to-many relationship
in Category Model you should have a relationship method:
public function products() {
return $this->hasMany(Product::class);
}
Blade:
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It
is working. Showing the correct ctgs
names
<div class=container>
#foreach ($ctg->products as
$product)
<h1> $product->name </h1>
#endforeach
</div>
#endforeach
I am getting above error while requesting to next page but I want posts title is as page title as well
#extends('layouts.app')
#section('pageTitle', $post->title)
#section('content')
Go Back
<br> <br>
<h1>{{ $post->title }}</h1>
<div class="">
<p>{!! $post->body !!}</p>
</div>
<hr>
<small>Written on: {{ $post->created_at }}</small>
<hr>
Edit
#endsection
public function show($id)
{
$post = Post::find($id);
return view('posts.show')->with('post', $post);
}
Post::find(...) can return null. You will have to make sure that you are actually receiving a model instance, the record exists, before trying to use it. You can use something like Post::findOrFail(...) to allow this to fail when it doesn't find a record. This would allow you to continue in the code knowing $post will be a valid instance.
Because the return type should be an array,
you can use this
public function show($id)
{
$post[] = Post::find($id);
return view('posts.show')->with('post', $post);
}
I am quite new to laravel so this might be silly mistake but I just can't figure out why it gives me this error. Right so on my website users can create posts and other users can like those posts. However, my implementation of the like system throws the following error:
ErrorException (E_ERROR)
Method Illuminate\Database\Eloquent\Collection::likes does not exist. (View: C:\xampp\htdocs\eventcw\resources\views\eventspage.blade.php)
This is my post controller method in charge of the likes:
public function postLikePost($post_id){
$loggedin_user = Auth::user()->id;
$like_user = Like::where(['user_id' => $loggedin_user, 'post_id' => $post_id])->first();
if(empty($like_user->user_id)){
$user_id = Auth::user()->id;
$post_id = $post_id;
$like = new Like;
$like->user_id = $user_id;
$like->post_id = $post_id;
$like->save();
return redirect()->route('events');
}else{
return redirect()->route('events');
}
}
My database relations seem fine,
here is my Like model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Like extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function post(){
return $this->belongsTo('App\Post');
}
}
Here is my likes table migration:
Schema::create('likes', function (Blueprint $table) {
$table->increments('id');
$table->integer('post_id');
$table->integer('user_id');
$table->timestamps();
});
Here is my post view:
<section class="row posts">
#foreach($posts as $post)
<div class="col-md-2 col-md-offset-3">
<article class="post">
<p>{{ $post->body }}</p>
<div class="info">Posted by {{ $post->user->first_name }} {{ $post->user->last_name }} on {{ $post->created_at }}</div>
<p>This post has {{ $posts->likes()->count() }} likes </p>
Like|
</article>
</div>
#endforeach
</section>
The error indicates you are calling likes() directly on a Collection.
$posts is the collection, which you are iterating over in your blade template.
Change {{ $posts->likes()->count() }} to {{ $post->likes()->count() }}
I am trying to update my data, but i keep getting this error message:
"Trying to get property of non-object (View: C:\xampp\htdocs\blog\resources\views\update.blade.php)".
This is my update.blade.php file
#extends ('layout')
#section ('title')
Update page
#stop
#section ('content')
<div class="row">
<div class="col-lg-12">
<form action="/todo/save" method="post">
{{ csrf_field() }}
<input type="text" class="form-control input-lg" name="todo"
value="{{ $todo->todo }}" placeholder="Type in to create a new todo">
</form>
</div>
</div>
<hr>
#foreach ($todo as $todo)
{{ $todo->todo }} <a href="{{ route('todo.update', ['id' =>$todo->id])
}}" class="btn btn-info btn-sm">Update</a> <a href="{{ route('todo.delete',
['id' =>$todo->id]) }}"class="btn btn-danger">Delete</a>
<hr>
#endforeach
#stop
my controller:
public function update($id){
//dd($id);
$todo = Todo::find($id);
return view('update')->with('todo', $todo);
}
and finally my update route:
Route::get('/todo/update/{id}', 'TodosController#update')-
>name('todo.update');
This is just some basic stuff, but im stuck in here for couple of hours now, and any help is highly appreciated!
Use findOrFail method on your controller to throw an Exception if $todo is empty
public function update($id){
$todo = Todo::findOrFail($id);
return view('update', compact('todo'));
}
The problem is also on your update.blade.php file. foreach $todo as todo, $todo has collection of eloquent model or eloquent model ? I think it's a eloquent model. So a loop doesnt have any sense.
That error would happen if todo were FALSE or some other non-object.
You can inspect it with a var_dump($todo);die(); in the controller.
find() will return either null or the model that is found. Assuming that the model is found, you're doing a for each on that model (foreach ($todo...)), which will iterate over the model's public properties. This is obviously not what you intend to do.
It looks to me like you're trying to loop over a list of your todos and print out edit/delete links. If this is the case, you need to get the list of your todos in your controller, pass it into your view, and fix your foreach statement.
Controller:
$todos = Todo::get();
// pass to view
View:
foreach ($todos as $todo)
I can`t access the values from this variable $post from controller:
in blade view:
#foreach($post as $p)
<div class="col-md-3">
<div class="boxpromo">
<h4>{{ $p->title }}</h4>
<p>{{ $p->post_description }}</p>
<div class="price">
<div class="data">{{ $p->out_date }}</div>
<div class="cost">{{ $p->price }}</div>
</div>
</div>
</div>
#endforeach
In controller i have:
public function postSearchTransport(Request $request, Post $post){
...
// create a new query builder
$post = $post->newQuery();
// add some filters from the user in the search query
if($request->has('searchWord')){
$post->where('title', 'LIKE', '%'.$request->input('searchWord').'%');
}
...//more filters
$post->paginate(5);
return view('searchVehicle.showSearchPost')->with('post', $post);
}
What i did wrong? I should be able to access in the view all the values from the query result, but i can`t this way.
Should i convert that $post std object from controller into an array then return it to the view???
You must pass to the view the returned value of paginate method like this :
$posts = $post->paginate(5);
return view('searchVehicle.showSearchPost')->with('post', $posts);