How to iterate nested data in laravel blade view? - laravel

I have below the draft implementation. The spec is to show the parent information and children-grandchildren information.
#foreach ($parent as $children)
<x-icons.chevron-right>
<h1>{{ $parent->name }}</h1>
#if($person->has('children'))
// go back at the top for nested for each
#endif
#endforeach
One solution that you may recommend is to create an iterative function. But my problem for that, it does not completely render my component-icon chevron-right.
#php
function showHTML($person) {
$html = '';
foreach($person as $children) {
$html .= `
<x-icons.chevron-right>
<h1>$person->name</h1>
`;
if ($person->has('children')) {
$html .= showHTML($person->children);
}
}
return $html;
}
#endphp
{!! showHTML($person) !!}
Just wondering if you guys have other solution for this to show nested with a component icon? I would appreciate any answer.

I encountered the same thing, and it did not take me long to figure out that we can re-iterate a component.
In my case, I just created a root component and re-iterated it if it had children.
So I don't need to loop it any longer.
So my usage would like this below:
<x-parent person="$person"></x-parent>
And my root component parent.blade.php. So If there is person has children I just re-iterate the component and pass his children as a prop:
#props(['person'])
<x-icons.chevron-right>
<h1>{{ $person->name }}</h1>
#if($person->has('children'))
<x-parent person="$person->children"></x-parent>
#endif

You can try => value on your foreach, that will fetch data array value from backend.
Or can you show your code on backend (controller), that can easy to help you
#foreach ($parent as $children => $value)
<x-icons.chevron-right>
<h1>{{ $parent->name }}</h1>
<h3>{{ $value->data }}<h3>
#endforeach

Related

Undefined variable: foods

hi guys am in need of assistance , i know this seems to be an easy one but am a bit confused , i have a foreach loop in my main.blade.php file, which shows foods from my database it works fine but when its clicked it meant to lead to the individual post and thats where i get the error
Undefined variable: foods
heres my foreach loop in main.blade.php file
#foreach($foods as $food)
<li class="item">
<a href="{{ route('Foods.show', $food->id) }}">
<img src="{{ Storage::disk('local')->url('food_images/'.$food->image ) }}" class="img-responsive w-25 p-3" alt="Food" >
<div class="menu-desc text-center">
<span>
<h3> {{ $food->title }}</h3>
{{ $food->body }}
</span>
</div>
</a>
<h2 class="white"> #{{ $food->price }}</h2>
</li>
#endforeach
heres my main.blade.php controller
public function LoadHome()
{
$foods = Food::all();
$foods = Food::orderBy('created_at','desc')->inRandomOrder()
->limit(12)
->get();
return view('pages.home')->withFood($foods);
}
and heres Foods.show controller function
public function show($id)
{
$foods = Food::Find($id);
return view('foods.show')->withFood($foods);
}
please what am i doing wrong
Have you tried passing data from your controller to the view using this something like this:
public function show($id)
{
$foods = Food::Find($id);
return view('foods.show')->with('foods', $foods);
}
or, if you're passing multiple variables to the view:
public function show($id)
{
$foods = Food::Find($id);
$something = "else";
return view('foods.show', compact('foods', 'something'));
}
Your view doesn't know what $foods is at that point, so it's always good practice to check that foods is set before the loop:
#if (isset($foods) && $foods->count() > 0)
#foreach($foods as $food)
...
#endforeach
#endif
See the official Laravel docs for more information.
If you want the variable to be named foods in the view then you would need to use withFoods not withFood:
return view(...)->withFoods($foods);
As mentioned in the other answers, there are other ways to pass data to the views as well.
There is no data being passed to a view.
This is how you pass data to a view:
public function LoadHome()
{
$foods = Food::orderBy('created_at','desc')->inRandomOrder()
->limit(12)
->get();
return view('pages.home', ['foods' => $foods])
}
If you always want to have $foods in main.blade.php you should place this in a service provider
View::share('foods', Food::orderBy('created_at','desc')->inRandomOrder()
->limit(12)
->get());
https://laravel.com/docs/7.x/views#sharing-data-with-all-views

Get related objects on the view

I have related model
class Myevent extends Model
{
public function photo()
{
return $this->hasMany('App\EventPhoto');
}
}
Ob blade if loop i get items Myevents
#foreach($evetns as $event)
<b>{{$event->name}}</b> <br>
{{$event->place}} <br>
{{$event->description}} <br>
#foreach($event->photo() as $item)
{{$item->id}}
#endforeach
#endforeach
How can I call related objects in a loop on blade?
You seem to be doing correctly, except for one single error $event->photo instead of $event->photo()
#foreach($event->photo as $item)
{{$item->id}}
#endforeach
To clear the confusion regarding brackets https://laraveldaily.com/calling-eloquent-from-blade-6-tips-for-performance/

laravel display data on a page based on id

I have a page that shows links with name of businesses that are retrieved in database like this:
Controller:
public function viewBusiness() {
// Return our "website" object
$business = Business::all();
// Pass the contents of the "html" property to the view
return view('viewBusiness', ['business' => $business]);
}
View:
#extends('master') #section('title', 'Live Oldham') #section('content')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->name) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Route:
Route::get('business/list', 'BusinessController#viewBusiness')->name('viewBusiness');
I then have added a function where user click on a link and it is taken to a page which displays all data for that specific business, however it diplays all data but for all businesses.
Controller:
function displayBusiness() {
$business = Business::all();
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}
View:
#foreach ($business as $businesses)
<p>{{$businesses->name}}</p>
<p>{{$businesses->email}}</p>
#endforeach
#foreach ($address as $addresses)
<p>{{$addresses->firstline_address}}</p>
<p>{{$addresses->secondline_address}}</p>
<p>{{$addresses->town}}</p>
<p>{{$addresses->city}}</p>
<p>{{$addresses->postcode}}</p>
<p>{{$addresses->telephone}}</p>
#endforeach
Route:
Route::get('business/{name}', 'BusinessController#displayBusiness')->name('displayBusiness');
Now here's the question, how can this code be modified so only a business that match either bussiness->name or business->id is displayed. (I guess name is taken when user clicks on a name.
Another question is how to restrict the url so that if localhost/business/{name} is not equal to any business->name in the database returns error? at the moment it shows the page no matter what you enter.
Thanks!
I do not know if I understood the question, but that may be the beginning of a solution ...
First view :
#extends('master') #section('title', 'Live Oldham')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->id) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Second Controller :
function displayBusiness($id) {
$business = Business::find($id);
$address = Address::find($id);
return view('displayBusiness', compact('business', 'address'));
}
Second View :
<p>{{$business->name}}</p>
<p>{{$business->email}}</p>
<p>{{$address->firstline_address}}</p>
<p>{{$address->secondline_address}}</p>
<p>{{$address->town}}</p>
<p>{{$address->city}}</p>
<p>{{$address->postcode}}</p>
<p>{{$address->telephone}}</p>
Second Route :
Route::get('business/{id}', 'BusinessController#displayBusiness')->name('displayBusiness');
Route parameters are available in the controller function as parameters. Now you can build a query with this function. If your query does not return any results, you can send the user back to the business overview.
function displayBusiness($name) {
$business = Business::where('name', $name)->orWhere('id', $name)->first();
if ($business === null)
{
// No business with this name or id found.
// Redirect to businesses list page.
}
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}

How to set null if relations doesn't exist?

In Model I have:
public function publisher()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
In template blade I try to show data User:
#foreach($announcement->offers as $key => $item)
<img src="{{url($item->publisher->photo)}}">
#endforeach
The Problem is that if there is no data in the User table, the program crashes because I can not get the property $item->publisher->photo.
How to fix it?
You can do something like this:
#if (empty($item->publisher))
It's empty
#else
<img src="{{ url($item->publisher->photo) }}">
#endif
Working on memory here, but you could use #forelse/ #empty. These directives can be used if the object your'e iterating over is empty:
#forelse($announcement->offers as $key => $item)
<img src="{{url($item->publisher->photo)}}">
#empty
//default image or message?
#endforelse
https://laravel.com/docs/5.4/blade#loops

How to pass parameters between controller methods

I am having problems getting the value of custom create method. What I want is to get the variable $student_id and place it on my findOrFail() in the index method as shown below:
ReservationController.php
public function index()
{
$student = Student::with(['sectionSubjects','sectionSubjects.section',
'sectionSubjects.subject'])->findOrFail(1); //$student_id
return $student->sectionSubjects;
}
public function create($id)
{
$student_id = $id;
$subjects = Subject::with('sections')->get();
return view('reservation.form',compact('subjects','student_id'));
}
Here's my route:
Route::resource('student', 'StudentController');
Route::resource('reservation', 'ReservationController', ['except' => ['create','show'] ]);
Route::get('reservation/{id}/create',
['as' => 'reservation.create', 'uses' => 'ReservationController#create'
]);
I have this form.blade.php that when a user click on a student it will be redirected to the custom create method in the ReservationController as seen below:
<div class="list-group ">
#inject('student', 'App\Http\Controllers\StudentController')
#foreach($student->index() as $s)
<div class="list-group-item">
<h4 class="list-group-item-heading">
{{ $s->first_name }} {{ $s->middle_name }} {{ $s->last_name }}</i>
</h4>
<h5>
ID No.: {{ $s->id_no }}</i>
</h5>
Edit Info
<a href="{{ route('reservation.create', $s->id ) }}"
class="btn btn-xs btn-danger">
Enroll
</a>
</div>
#endforeach
</div>
Now in the index method in the ReservationController, I want to fetch only values that are related to that $student_id. However, I cannot figure out to achieve this. Can anyone suggest ways to solve this?
Actually you don't have any problem expect Logic problem.
Your Controller not designed in the correct way.
You need to have something like this
//List all subjects
public function index() {
return view('reservation.form')->with('subjects', Subject::with('sections')->get());
}
//List a single subject
//If i didn't misunderstood you, you can remove this one according to the source code you're using.
public function show($id) {
return view('reservation.oneSubject')->with('subject', Subject::find($id));
}
//Enroll a student to subject
public function enroll($id, $student_id) {
//Find the section for $id
//Add student_id to that section
}
And you need to define one extra route could be GET or POST in this example i'm using GET
Route::get('/reservation/{id}/enroll/{student_id}', 'ReservationsController#enroll');
What logic should i follow?
List all subjects (will call index())
Select one subject (will call show($id))
Show students.
Click add button (will call enroll($id, $student_id)
How do i pass $id, $student_id to enroll?
Your reservations resource will have these routes.
/reservations
/reservations/{id}/store
etc..
id parameter in your example, Pointing to Subject not Student.
Let's say you've a show($id) function which will show single subject and list of students,
return view(...)->with('subject', Subject::find($id)->with('students', YOUR_STUDENTS);
In the view, iterate through students, assuming you've $students
#foreach($students as $student)
Enroll student
#endforeach
I don't have show() function!
Since you don't have a show function that will display single subject, Same logic will apply here,
Iterate through subjects
Display subject
Iterate throught students
Generate anchor tags as the example above
So you'll have something like this,
#foreach($subjects as $subject)
<h1>{{ $subject->title }}</h1>
#foreach($students as $student)
<div class="students">
<h2> {{ $student->name }}</h2>
Enroll
</div>
#endforeach
#endforeach

Resources