Laravel and nested foreach of database query error - php

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.

Related

Laravel: Dynamic tabs don't show the correct data?

I am trying to use dynamic tabs in laravel and iam kinda new to it. Iam stuck in it for like 2 days.
I have two variables that getting data from tables in mysql.
$stations = Station::select('id', 'name')->get();
// return $staions;
$queues = Queue::withTrashed()
->oldest()
->get();
// return $queues;
The data in $schedules:
[
{
"id":1,
"name":"siinay"
},
{
"id":2,
"name":"jigjiga"
},
{
"id":3,
"name":"Idaacada"
},
{
"id":4,
"name":"Xero Awr"
}
]
And the data in the $queues:
So the problem is here in dynmaic tabs: I have wanted to display station names in the nav-tabs and queues in the tab-content. So i did it like this.
<ul class="nav nav-tabs">
#forelse ($stations as $station)
<li >
<a data-toggle="tab" href="#tab-{{ $station->id }}" >
{!! $station->name !!}
</a>
</li>
#empty
#endforelse
</ul>
<div style="margin-top: 15%" class="tab-content">
#foreach($queues as $queue)
#if($queue)
<div id="tab-{{ $queue->station_id}}" class="tab-pane fade">
<p>{!! $queue->bus_number !!}</p>
</div>
#else
<div>empty</div>
#endif
#endforeach
</div>
when i run the above code, it only showing the last queue bus_number per each sttions. every stations queue
Oldest is indeed the oldest, it's the opposite to first. Try this to get a collection:
$queues = Queue::withTrashed()
->orderBy('id', 'desc')
->get();
In the view (simplified):
<ul class="nav nav-tabs">
#foreach ($stations as $station)
<li>
<a data-toggle="tab" href="#tab-{{ $station->id }}">
{{ $station->name }}
</a>
</li>
#endforeach
</ul>
<div style="margin-top: 15%" class="tab-content">
#foreach($queues as $queue)
<div id="tab-{{ $queue->station_id }}" class="tab-pane fade">
<p>{{ $queue->bus_number }}</p>
</div>
#endforeach
</div>
No need to check for empty. Each one is a table record. Unless you want to check on bus_number or station_id.

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>

Trying to get property of non-object in aside

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>

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.

dynamic accordion with bootstrap

I'm having a hard time getting this dynamic accordion to work properly.
I'm fetching accordion title from MySQL database and trying to create a dynamic accordion based on number of rows in my database.
As of right now, I'm only able to create single tab with first title in my database.
<?php
foreach ($variable as $key);
?>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" style="margin-right:50%;" > <img src="image.jpeg" class="event-icon"> <?php echo $key['title']?>;</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
<p>Event content
</p>
</div>
</div>
</div>
</div>
</div>
I'm trying to create the following html structure when the foreach loop runs.
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" style="margin-right:50%;" > <img src="image.jpeg" class="event-icon"> <?php echo $key['title']?>;</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
<p>Event content
</p>
</div>
</div>
</div>
Any suggestion is highly appreciated.
You have to add at the end of your foreach loop, like this:
<?php endforeach; ?>
Also you have to change ; -> : in your foreach header:
foreach ($variable as $key);
to:
foreach ($variable as $key):
//^See here
Looks like you have a problem with the alternative syntax for foreach
foreach ($variable as $key);
should be
foreach ($variable as $key):
semicolon (;) should be a colon (:)
it also ends with a endforeach semicolon
endforeach;

Categories