ErrorException Invalid argument supplied for foreach() - php

So i was trying to get a full post from the database by id, so when i click this link Lanjutkan Baca <img src="asset/img/icons/double-arrow.png" alt="#"/> it will take me to the url /post/read/{id} and give me the fullpost, but it shows that error,
i search for the same problem and found that that the problem is $blogs variable is an array, but the value it return is not, can anybody show me how to make the method or the view in my code to return an array and show the full post ?
this is my view read.blade.php
#foreach ($blogs as $blog)
<div class="top-meta">{{ Carbon\Carbon::parse($blog->created_at)->format('d-m-Y') }} / di Rakitan</div>
<h3>{{ $blog->name }}</h3>
<p>{!! $blog->message !!}</p>
#endforeach
this is my BlogController.php
public function getFullPost($blog_id) {
$blogs = Blog::all()->where('blogs.id', '=', $blog_id)->first();
return view('post.read')->with(compact('blogs'));
}
this is the model Blog.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
protected $fillable = ['name','message'];
}
and this is the routes
Route::get('/post/read/{blog_id}', 'BlogController#getFullPost')->name('post.read');

Use 'get' method to get all rows with cobditions
public function getFullPost($blog_id) {
$blogs = Blog::where('id', '=', $blog_id)->get();
return view('post.read')->with(compact('blogs'));
}
Add table name in Model to reference in Blog model

Related

Trying to get property 'cover_image' of non-object (View: C:\Users\BWB\Documents\Laravel\asperablogs\resources\views\blogs\blogs.blade.php)

So I'm making a blog website and I'm implementing tags. I keep getting the error in the title and not sure what I'm supposed to do. I've looked through similar questions here but they look different from how i've done it. Im using pivot tables for the the tags. When I did it with the posts only it worked well and displayed everything
here is the index method from my posts controller.
public function index()
{
$posts = Post::all()->sortByDesc('created_at');
return view('blogs.blogs', compact('posts'));
}
here is the index method from my tag controller.
public function index(Tag $tag){
$posts = $tag->posts();
return view('blogs.blogs')->with('posts',$posts);
}
Here is how I'm outputting it in the view
#foreach($posts as $post)
<div class="well row">
<div class="col-md-4">
<img style="width: 100%" src="/storage/cover_images/{{$post->cover_image}}" alt="">
</div>
<div class="col-md-8">
<h3> {{$post->title}}</h3>
<h3>{{$post->created_at}}</h3>
</div>
</div>
#endforeach
This is my tags model
public function posts() {
return $this->belongsToMany(Post::class);
}
public function getRouteKeyName()
{
return 'name';
}
Error
Your error comes from the fact that the variable $post within your foreach loop has returned as a non-object.
Probable Cause
That $posts is not being returned as a collection but rather a query builder instance
$posts = $tag->posts();
If you have built an eloquent relationship between a Tag model and a Post model, when you access this as a method (i.e. $tag->posts()) you will get an eloquent query builder instance. If you access this as a property (i.e. $tag->posts), it will return an eloquent collection.
Suggestion
Try passing the posts to the view as a collection
public function index(Tag $tag) {
return view('blogs.blogs', [
'posts' => $tag->posts
]);
}
And try using a #forelse loop to catch the instances where you have no posts
#forelse ($posts as $post)
#empty
#endforelse

Laravel multiple controller functions one route

What I'm trying to achieve is post all news by #foreach and between the #foreach do another #foreach to post all comments with the ID from the news post.
I'm unsure on how to pass this ID, to the getNewsComments function.
My controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\News;
use App\newsComments;
class newsController extends Controller
{
public function getAllNews(){
$results = News::all();
return view('index')->with('news', $results);
}
}
Route:
Route::get('/', 'newsController#getAllNews');
News model:
class News extends Model
{
// set table
protected $table = 'lg_news';
public function newsComments(){
return $this->hasMany('App\newsCommments');
}
}
Comment model:
class newsComments extends Model
{
// set table name
protected $table = 'lg_newscomments';
}
view
#foreach ($news as $article)
#foreach($news->$newsComments as $comment)
#endforeach
#endforeach
Error:
Undefined variable: newsComments (View:
C:\xampp\htdocs\resources\views\index.blade.php)
Change this line:
return view('index')->with('news', $results);
to
return view('index', ['news' => $results]);
and it probably will work.
PS: with() function will set a session! It will not pass a variable to view.
You don't need multiple routes you just need to have two tables related to each other with 1:N relationship
Article (1) -> Comments (N)
Then you will create a model for each table and create the relation like explained in the Laravel documentation
One to Many relationship in Laravel
Then you will fetch all posts and pass them to the view:
public function getAllArticles()
{
$posts = Post::all();
return view('view-name', $posts);
}
And at the end, create a view and show posts and comments:
#foreach($posts as $post)
{{ $post->title }}
{{ $post->body }}
#foreach($post->comments as $comment)
{{ $comment->title }}
{{ $comment->body }}
#endforeach
#endforeach
Reminder: $post->comments , comments is the method name defined in the model where you create the relationship
Define route at web.php:
Route::get('/', 'ControllerName#getAllArticles');
Go to localhost:8000/ (or to your site domain if the site is hosted) to see the result

Get value from one to many relationship. Laravel

I have two models Vehicles and Image,
Vehicle hasMany images
public function images(){
return $this->hasMany('App\Image');
}
Image belongsTo a Vehicle:
public function vehicle(){
return $this->belongsTo('App\vehicle');
}
I've retrieved vehicles like:
In Controller:
$ads=ads::orderBy('views','desc')->get();
foreach ($ads as $ad) {
$popularvehicles[]=vehicles::where('id',$ad->Vehicleid)->get()->toArray();
}
View:
#foreach($popularvehicles as $popularvehicle)
#foreach($popularvehicle as $vehicle)
{{$vehicle['vname']}}
#endforeach
#endforeach
Now, I want to retrieve an image that belongs to $vehicle.
I've tried following syntax:
#foreach($popularvehicles as $popularvehicle)
#foreach($popularvehicle as $vehicle)
#foreach($vehicle->image as $image)
<a href="page-product-details.html">
<img src="{{ asset("images/$image->title") }}" alt="{{ $image->title }}" >
</a>
#endforeach
#endforeach
#endforeach
But it is throwing an exception of: Trying to get property of non-object.
What can I do to make it right?
Just a simple example:
You have a model, the model has details in another model.
class Vehicle extends Model
{
protected $fillable = [
'brand',
'etc',
];
public function details()
{
return $this->belongsToMany('App\VehicleDetails');
}
}
And the details model:
class VehicleDetails extends Model
{
protected $fillable = [
'color',
'engine',
];
public function vehicle() {
return $this->belongsTo('App\Vehicle');
}
}
I usually use transformers to return the needed data, but you don't have to. To make use of the hasMany you can call it like this:
return Vehicle::find($vehicleId); // Retrieve the vehicles from the server
// the object retrieved has the details.
$vehicle->details; // then you can use contains the details
// example:
#foreach($vehicle->details as $details)
<a href="page-product-details.html">
<img src="{{ asset("images/$details->imagetitle") }}"
alt="{{ $details->title }}" >
</a>
#endforeach
The returned object contains the details and you can loop trough it how ever you want.
Without more details about how you retrieve the data I can't be more specific.
I can see 2 problems;
Your popularvehicles is an array of arrays
$popularvehicles[]=vehicles::where('id',$ad->Vehicleid)->get()->toArray();
The toArray is turning everything into an array. You no longer have Vehicle objects. https://laravel.com/docs/5.2/collections#method-toarray
Use ->all() instead.
Second Problem
#foreach($vehicle->image as $image)
You want to use $vehicle->images

Showing related table information in blade template laravel

I have the following relationship between my tables
In my Models i have the following code:
Location Model:
public function member() {
return $this->belongsTo('App\Member','member_id');
}
Member Model:
public function locations(){
return $this->hasMany('App\Location','member_id');
}
Now in my Location controller I created the following function.
public function getFinalData(){
$locations = Location::with('member')->whereNotNull('member_id')->get();
return view('locations.final-list',['locations'=>$locations]);
}
In my blade template however, I am unable to iterate through the member properties
<ul>
#foreach($locations as $location)
<li>{{$location->id}}</li>
<li>
#foreach($location->member as $member)
{{$member->id}}
#endforeach
</li>
#endforeach
</ul>
This gives me the following error:
Trying to get property of non-object (View:locations/final-list.blade.php)
update: The result i'm trying to achieve corresponds to this query
SELECT locations.location_id,locations.name,members.first_name, members.last_name , locations.meters
FROM locations,members
WHERE locations.member_id = members.id
Update 2:
So i tried to access a single location with a single attached to it and that works perfectly
public function getFinalData(){
//$locations = Location::with('member')->whereNotNull('member_id')->get();
$location = Location::find(0);
return view('locations.final-list',['location'=>$location]);
}
in final-list
$location->member->first_name
**Update 3 **
Tinker Output for one record :
In your Location model, rewrite below function:-
public function member()
{
return $this->belongsTo('App\Member', 'id');
}
Get all locations with member detail as below:-
$locations = Location::with('member')->get();
Hope it will work for you :-)
For showing related tables information in blade is as shown:
Model Relations
Location Model:
public function member() {
return $this->belongsTo('App\Member','member_id');
}
Member Model:
public function locations(){
return $this->hasMany('App\Location','member_id');
}
Get all locations in your controller
$locations = Location::all();
return view('locations.final-list', compact('locations'));
Or
$locations = Location::orderBy('id')->get();
return view('locations.final-list', compact('locations'));
Inside your view(blade) write the following code:
<div>
#if($locations)
#foreach($locations AS $location)
<div>{{ $location->id }}</div>
#if($location->member)
#foreach($location->member AS $member)
<div>
{{ $member->id }}
</div>
#endforeach
#endif
#endforeach
#endif
</div>

Trouble retrieving data laravel4(oneToMany)

Okay so I just started learning Laravel and its fantastic. I just got stuck trying to retrive all the post from a user. Here is my code
models/User.php
public function posts()
{
$this->hasMany('Post');
}
models/Post.php
public function user()
{
$this->belongsTo('User');
}
controller/UserController.php
public function getUserProfile($username)
{
$user = User::where('username', '=', $username)->first();
$this->layout->content = View::make('user.index', array('user'=>$user));
}
views/user/index.blade.php
<div class="show-post">
<ul>
<li>{{ $user->posts }}</lo>
</ul>
</div>
I also tried:
#foreach($user->posts as $post)
<li>{{$post->post}}</li>
#endforeach
So im having trouble displaying the post for each specific user. Thank you.
So with the help of #WereWolf- The Alpha I was able to solve it and make my code better, If you notice I forgot to return my relationship functions. example:
Notice I hadn't returned it before
models/Post.php
public function users()
{
return $this->belongsTo('users');
}
But also the way I was querying my database was inefficient so Alpha showed me Eager Loading
http://laravel.com/docs/eloquent#eager-loading
example of controller
public function getUserProfile($username)
{
$user = User::with('posts')->where('username', '=', $username)->first();
$this->layout->content = View::make('user.index', array('user'=>$user));
}
and finally the view:
div class="show-post">
#foreach($user->posts as $post)
{{ $post->post }}
#endforeach
</div>
Actually $user->posts returns a collection of Post model so when you try this
{{ $user->posts }}
Laravel tries to echo that collection object which is not possible. You may try foreach loop instead:
#foreach($user->posts as $post)
{{ $post->somepropertyname }}
#endforeach
It's also possible to do something like this:
// Get first post->somepropertyname
{{ $user->posts->first()->somepropertyname }}
// Get last post->somepropertyname
{{ $user->posts->last()->somepropertyname }}
// Get first post->somepropertyname (same as first)
{{ $user->posts->get(0)->somepropertyname }}
// Get second post->somepropertyname from collection
{{ $user->posts->get(1)->somepropertyname }}
// Get the post->somepropertyname by id (post id) 2
{{ $user->posts->find(2)->somepropertyname }}
Also you may use eager loading like this (better):
$user = User::with('posts')->where('username', '=', $username)->first();
You may like this article about Cocllection.
Update: Also use return in model methods, like:
public function posts()
{
return $this->hasMany('Post');
}

Categories