Trying to get property of non-object in aside - php

I´m trying to do a simple blog with Laravel 5.3. Index page include aside with categories and tags, and we can filter different post with categories or tags names.
In routes I have this.
Route::get('categories/{name}',[
'as'=>'front.search.category',
'uses'=>'FrontController#searchCategory'
]);
Route::get('tags/{name}',[
'as'=>'front.search.tag',
'uses'=>'FrontController#searchTag'
]);
In Article
public function scopeSearchCategory($query,$name){
$query->where('name','=',$name);
}
In Tag
public function scopeSearchTag($query,$name){
$query->where('name','=',$name);
}
In FrontController.
public function searchCategory($name){
$tags=Tag::all();
$sliders=Slider::all();
$categories = Category::SearchCategory($name)->first();
$articles = $categories->articles()->paginate(5);
$articles->each(function($articles){
$articles->category;
$articles->images;
});
return view('front.index')->with('articles', $articles)->with('sliders', $sliders)->with('categories', $categories)->with('tags',$tags);
}
public function searchTag($name){
$categories=Category::all();
$sliders=Slider::all();
$tags = Tag::SearchTag($name)->first();
$articles = $tags->articles()->paginate(5);
$articles->each(function($articles){
$articles->category;
$articles->images;
});
return view('front.index')->with('articles', $articles)->with('sliders', $sliders)->with('categories', $categories)->with('tags',$tags);
}
In aside
<aside class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">{{trans('app.title_categories')}}</h2>
</div>
<div class="panel-body">
<ul class="list-group">
#foreach($categories as $category)
<a href="{{route('front.search.category',$category->name)}}">
<li class="list-group-item">
<span class="badge">{{$category->articles->count()}}</span>
{{$category->name}}
</li>
</a>
#endforeach
</ul>
</div>
</aside>
<aside class="panel panel-success">
<div class="panel-heading">
<h2 class="panel-title">Tags</h2>
</div>
<div class="panel-body">
<ul class="list-group">
#foreach($tags as $tag)
<a href="{{route('front.search.tag',$tag->name)}}">
<li class="list-group-item">
<span class="badge">{{$tag->articles->count()}}</span>
{{$tag->name}}
</li>
</a>
#endforeach
</ul>
</div>
</aside>
When a click on aside href to filter tags or categories return 'Trying to get property of non-object'. If I remove scopeSearchs and put in FrontController functions $Tag:all() or Category:all() href works, but filter fail, return all post. ¿Any idea why return this error? ¿Can´t do foreach if return one object?

You should use
$tags = Tag::searchTag($name)->first();
When you are using scope function it should always be camelCase
so searchTag() should be start with small s not capital s
You should remove foreach
use this
<a href="{{route('front.search.tag',$tags->name)}}">
<li class="list-group-item">
<span class="badge">{{$tags->articles->count()}}</span>
{{$tags->name}}
</li>
</a>

Related

Showing dynamic items list using two tables in codeigniter php

I have two tables one having advert info which includes id for images table associated with the advert. I am showing the advert information in one single page, how do I send both arrays to the view page. If I write the select for both tables, I get multiple lines since I have multiple images for an advert.
My model functions
public function get_adverts()
{
//$this->db->select();
//$this->db->from('adverts');
$db_query='select adverts.id,adverts.address,adverts.title,adverts.item_condition, adverts.add_type, adverts.price, adverts.negotiable, adverts.product_description, countries.country_name,states.state_name, cities.city_name, product_pictures.picture_file_name
FROM adverts,countries,cities,states, product_pictures
WHERE adverts.country_id=countries.id and adverts.city_id=states.id and adverts.area=cities.id and adverts.id= product_pictures.add_id';
$query = $this->db->query($db_query);
return $query->result();
}
public function get_pictures()
{
//$this->db->select();
//$this->db->from('adverts');
$db_query='select product_pictures.picture_file_name
FROM adverts,product_pictures
WHERE adverts.id=product_pictures.add_id';
$query = $this->db->query($db_query);
return $query->result();
}
and my control
public function get_products()
{
// gets all dvertes in the system
$this->load->model('Product_model');
$data['products']=$this->Product_model->get_adverts(); // get database query output to the array
$data['images']=$this->Product_model->get_pictures();
$array_info2 = array(
"title" => "Not Found"
);
$this->load->view('include/header', $array_info2);
$this->load->view('include/navbar_logged_in');
$this->load->view('Site/view_adverts',$data);
$this->load->view('include/footer');
}
This lists all images under one advert, my view portion given below:
<div class="container">
<?php foreach($products as $product):?>
<div class="ad-listing-list mt-20">
<div class="row p-lg-3 p-sm-5 p-4">
<div class="col-lg-4 align-self-center">
<?php foreach($images as $image):?>
<img class="image img-thumbnail" src="<?php echo base_url('/uploads/advert_images/thumbs/'.$image->picture_file_name);?>" >
<?php endforeach;?>
</div>
<div class="col-lg-8">
<div class="row">
<div class="col-lg-6 col-md-10">
<div class="ad-listing-content">
<div>
<?php echo $product->id." ".$product->title;?>
</div>
<ul class="list-inline mt-2 mb-3">
<li class="list-inline-item"> <i class="fa fa-folder-open-o"></i> Electronics</li>
<li class="list-inline-item"><i class="fa fa-calendar"></i>26th December</li>
</ul>
<p class="pr-5"><?php echo $product->product_description;?></p>
</div>
</div>
</div>
</div>
</div>
</div>
<?php endforeach;?>
</div>

Order the categories by the number of conferences associated with each category

Im getting all the categories like:
public function index(){
return view('home')
->with('categories', Category::orderBy('created_at', 'desc')->get())
->with('conferences', Conference::orderBy('created_at','desc')->where('status','P')->take(8)->get())
}
Then in the blade file I show the categories like below. But do you know how to order the categories by the number of conferences associated with each category? That is, show first the categories that have more conferences associated with it. Do you know how that can be achieved?
<div class=" d-md-block">
<div class="container">
<div class="row">
<div class="col p-0 m-0">
<ul class="Categories__Menu">
#foreach($categories->take(6) as $category)
<li class="">
{{$category->name}}
</li>
#endforeach
<li><a data-toggle="modal" id="showCategories" data-target=".bd-example-modal-lg" href="">More <i class="fa fa-caret-down" aria-hidden="true"></i></a></li>
</ul>
</div>
</div>
</div>
</div>
Use this.
Category::withCount('conferences')->orderBy('conferences_count', 'desc')->get();

how to get an item in an iteration using foreach?

Im having a hard time extracting an item in an array, for example trying to retrieve a post in posts.
this is the error
keep in mind everything works, i can extract posts but im trying to successfully show the delete button to users.
im following laravel polices, to show a delete button for the user who made the post
laravel.com/docs/5.5/authorization#via-blade-templates
Undefined variable: post (View:
/Applications/MAMP/htdocs/eli42/resources/views/home.blade.php)
this is what i have so far
public function index()
{
$posts = Post::with('user')->get();
return view('home', compact('posts'));
}
home.blade.php
<div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts ">
<div id="eli-style-heading" class="panel-heading"><% post.user.name %></div>
<div class="panel-body panel">
<figure>
<p> <% post.body %></p>
<p> <% post.created_at %></p>
</figure>
<span>
#foreach($posts as $post)
#if(Auth::user()->can('delete',$post) )
<i style="color:red;" class="glyphicon glyphicon-remove" ng-click="deletePost(post)">
</i>
#endif
#endforeach
<span>Edit</span>
</span>
</div>
</div>
I'm not sure what im doing wrong
it needs to show one close button not 3
return returns program control to the calling module. Execution
resumes at the expression following the called module's invocation.
You are sending request on method getPosts for collecting posts. So you don't need to return posts variable by index method. Then you need it in getPosts.
You are using angular and in this case you need to have variable about delete availability but this variable you need in javascript. Just add it in controller and send to angular, then use ng-if attribute in angular for show/hide delete button.
In this case you need to change getPosts method as it is in answer what will add deletable variable in every post then you can use post.deletable in angular. What you need to end this task is that add ng-if="post.deletable" to <i> tag what means if delete post is available show this tag(button).
Controller
public function getPosts()
{
return response()->json(Post::with('user')->get()->map(function(Post $post){
return collect($post->toArray())->put('deletable', auth()->user()->can('delete', $post));
}));
}
public function index()
{
return view('home');
}
It looks like you are using Angular. For this case your blade seems good.
In this case you don't need $posts variable in view and you don't need #foreach too in blade.
<div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts ">
<div id="eli-style-heading" class="panel-heading"><% post.user.name %></div>
<div class="panel-body panel">
<figure>
<p> <% post.body %></p>
<p> <% post.created_at %></p>
</figure>
<span>
<i style="color:red;" class="glyphicon glyphicon-remove" ng-click="deletePost(post)" ng-if="post.deletable"></i>
<span>Edit</span>
</span>
</div>
</div>
You should try this:
Function
public function index() {
$posts = Post::with('user')->get();
return view('home', compact('posts'));
}
home.blade.php
<div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts ">
<div id="eli-style-heading" class="panel-heading"><% post.user.name %></div>
<div class="panel-body panel">
<figure>
<p> <% post.body %></p>
<p> <% post.created_at %></p>
</figure>
<span>
#foreach(posts as $post)
#if(Auth::user()->can('delete',$post->id) )
<i style="color:red;" class="glyphicon glyphicon-remove" ng-click="deletePost(post)">
</i>
#endif
#endforeach
<span>Edit</span>
</span>
</div>
</div>

Laravel: Calling method of a controller class from blade template

How can I call a method of a controller from blade template and receive the data is returned by the method. For Example:
MeetingRoomController
class MeetingRoomController extends \BaseController
{
public function index()
{
//get all the meeting room
$meetingRoomCountry = MeetingRoom::select('country')->distinct()->orderBy('country')->get();
return View::make('index')->with('meetingroom', $meetingRoomCountry);
}
public function findLocationForNavBar( $country )
{
$meetingRoomLocation = MeetingRoom::select('location')
->distinct()
->where('country', '$country')
->orderBy('country')
->get();
return View::make('index')- >with('meetingroomLocation', $meetingRoomLocation);
}
}
View - index.blade.php
<div id="dropdown-lvl1" class="panel-collapse collapse">
<div class="panel-body">
<ul class="nav navbar-nav">
#foreach($meetingroom as $key => $value)
<li class="panel panel-default" id="dropdown">
<a data-toggle="collapse" href="#dropdown-lvl2">
<span class="glyphicon glyphicon-off"></span> {{$country = $value->country}} <span class="caret"></span>
</a>
<div id="dropdown-lvl2" class="panel-collapse collapse">
<div class="panel-body">
<ul class="nav navbar-nav">
<li>Location</li>
</ul>
</div>
</div>
</li>
#endforeach
</ul>
</div>
</div>
I want to collect the location based on corresponding country. According to my logic, First of all I collected the distinct country then searched the location by findLocationForNavBar method in MeetingRoomController.
If you're using Laravel 5.1, you could try a Service Injection from your blade template.
http://laravel.com/docs/5.1/blade#service-injection
Example from the docs:
#inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
You can do all this stuff in the index() method and send location and country to view.

Laravel and nested foreach of database query error

I am building a menu on laravel.
In blade layout i have:
#foreach ($menu1 as $menu1)
{{$menu1->nome}}
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
<ul class="list-unstyled">
#foreach ($menu2 as $menu2)
<li> {{$menu2->nome}} </li>
#endforeach
</ul>
</div>
</div>
</div>
#endforeach
in my controller i pass 2 query.
public function menu($lingua)
{
return View::make('index', ['menu1'=>DB::table('cat_nome')->join('lingua', 'cat_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(array('cat_nome.nome')),
'menu2' => DB::table('campo_nome')->join('lingua', 'campo_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(array('campo_nome.nome'))]
);
}
I tried to UNnest the foreach and everything works fine. When i try to nest the foreach i get
Trying to get property of non-object
#foreach ($menu2 as $menu2)
That line is most likely the culprit. You cannot use the same variable name twice in a foreach loop like that and expect good results. The second one is supposed to be what each entry in $menu2 will be scoped to during each iteration of the loop.
See the foreach documentation
Try changing the loop to look more like this:
#foreach ($menu2 as $innerMenu)
<li> {{$innerMenu->nome}} </li>
#endforeach
I would suggest doing the same thing for your outer menu as well.

Categories