Laravel nested foreach by 2 different Models
Laravel nested foreach by 2 different Models
I tried
this. problem is, How to foreach data from different Models?
Trying to get property of non-object (View: C:wamp64wwwzainsurgaltresourcesviewschoicesindex.blade.php)
Controller
$duplicates = Question::selectRaw("count('id') as total, topic_id")->with('topic', 'topic.choices')->groupBy('topic_id')->get();
$choices = Choice::where('user_id',Auth::id())->pluck('question_number')->toArray();
return view('choices.index',compact('duplicates','choices'));
View
@foreach ($duplicates as $duplicate)
<tr>
<td style="text-align: center;">{{ $duplicate->topic->id }}</td>
<td style="text-align: center;">{{ $duplicate->topic->title }}</td>
<td style="text-align: center;">{{ $duplicate->total }}</td>
<td style="text-align: center;">
@foreach ($choices as $choice)
{{ $choice->question_number }}
@endforeach
</td>
<td>
<a class="btn btn-default" href="choices/{{ $choice->id }}/edit">Шинэчлэх</a></td>
</tr>
@endforeach
result of dd($choices) before foreach
array:34 [▼
0 => 5
1 => 5
2 => 0
3 => 0
4 => 0
...
31 => 0
32 => 0
]
Added this Controller full code
public function index(Choice $choice){
$duplicates = Question::selectRaw("count('id') as total, topic_id")->with('topic', 'topic.choices')->groupBy('topic_id')->get();
$choices = Choice::where('user_id',Auth::id())->pluck('question_number');
$user = Choice::where('user_id','=',Auth::id())->first();
if ($user === null) {
$too = 0;
return redirect()->route('choices.create');
}
else{
$too = 1;
return view('choices.index',compact('too','duplicates','choices'));
}
}
Full code of View
<table align="center" border="1" cellpadding="1" cellspacing="1" style="height:106px; width:100%">
<thead>
<tr>
<th colspan="5" scope="col">
<h3 style="text-align: center;"><b>Шалгалтын цаг сонголт</b></h3>
<select style="text-align: center;" name="time" class="form-control">
<option value="30:01">30 минут</option>
<option value="40:01">40 минут</option>
<option value="50:01">50 минут</option>
<option value="60:01">60 минут</option>
<option value="70:01">70 минут</option>
<option value="80:01">80 минут</option>
<option value="90:01">90 минут</option>
</select></th>
</tr>
<tr>
<th style="text-align: center;" scope="col">№</th>
<th style="text-align: center;" scope="col">Нэр</th>
<th style="text-align: center;" scope="col">Нийт асуултын тоо</th>
<th style="text-align: center;" scope="col">Асуултын тоо</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (array_combine($duplicates->toArray(), $choices->toArray()) as $duplicate => $choice){
<tr>
<td style="text-align: center;">{{ $duplicate->topic->id }}</td>
<td style="text-align: center;">{{ $duplicate->topic->title }}</td>
<td style="text-align: center;">{{ $duplicate->total }}</td>
<td style="text-align: center;">{{ $choice->question_number }}</td>
<td><a class="btn btn-default" href="choices/{{ $choice->id }}/edit">Шинэчлэх</a></td>
</tr>
@endforeach
</tbody>
</table>
brwanobr oawnbrnoawbn obrawnor bonb rwanobrwn obrawnobrw aonbanobnaowbonwab onbonawb onrwa onbr awnob rwnobrno rbawnorb noawbnorba nobrwaonbrwa
dd($variable)
when i
dd($choices)
it gives me right datas.– Ruka Xing
Jun 25 at 2:47
dd($choices)
Please check my updated question please. @srimaln91
– Ruka Xing
Jun 25 at 2:48
Your foreach loop looks correct. But your
dd($choices)
only returns array of integer, while you are trying to access it like $choice->question_number
. Try to change it to just {{ $choice }}
in your foreach choices loop.– Joshua Stephen
Jun 25 at 2:51
dd($choices)
$choice->question_number
{{ $choice }}
@JoshuaStephen same error sir.
– Ruka Xing
Jun 25 at 2:52
4 Answers
4
Try to replace
$choices = Choice::where('user_id',Auth::id())->pluck('question_number')->toArray();
with $choices = Choice::where('user_id',Auth::id())->get();
as when you pluck you won't get the key question_number
and will get the error trying t o get property of undefined
$choices = Choice::where('user_id',Auth::id())->get();
question_number
trying t o get property of undefined
care to add an explanation?
– Wreigh
Jun 25 at 7:20
Good news It almost works, I looped data. but bad news. i looped data for each line. It's like i printed all
data
in column 1, and also printed all data
in column 2.– Ruka Xing
Jun 25 at 7:37
data
data
Can you please explain what exactly you want? and if this works for you then please accept the answer.
– Mayuri Pansuriya
Jun 25 at 7:44
i want foreach 2 collection in 1 foreach. its like.
@foreach ($duplicates as $duplicate)
and {{ $duplicate->topic->id }}
and {{ $choice->question_number }}
– Ruka Xing
Jun 25 at 8:13
@foreach ($duplicates as $duplicate)
{{ $duplicate->topic->id }}
{{ $choice->question_number }}
You can use relationship for choice in the first query itself like
with(['choice' => function($q) { $q->where('user_id',Auth::id()); });
– Mayuri Pansuriya
Jun 25 at 9:07
with(['choice' => function($q) { $q->where('user_id',Auth::id()); });
trying to access $choice->id
out of foreach loop in your view
$choice->id
you have used pluck() in your controller
so in your view you can't use $choice->question_number
$choice->question_number
so you need to change controller
query or you can use below
@foreach ($duplicates as $duplicate)
@foreach ($choices as $choice)
// here only can use like this
{{ $choice }}
//{{ $choice->question_number }}
@endforeach
// this $choice->id out of foreach loop
<a class="btn btn-default" href="choices/{{ $choice->id }}/edit">Шинэчлэх</a></td>
@endforeach
or as @Mayuri Pansuriya said you need to change your controller query then you can access
$choices = Choice::where('user_id',Auth::id())->get();
then you can access in your view
<td style="text-align: center;">
@foreach ($choices as $choice)
{{ $choice->question_number }}
@endforeach
</td>
In your controller don't use toArray() if you want both items to be objects. The best way I know of to do this in the view is to use array_combine() if the objects are the same length.
Controller
$duplicates = Question::selectRaw("count('id') as total, topic_id")->with('topic', 'topic.choices')->groupBy('topic_id')->get()->toArray();
$choices = Choice::where('user_id',Auth::id())->get()->toArray();
return view('choices.index',compact('duplicates','choices'));
View
@for($i=0; $i< count($duplicates); $i++){
<tr>
<td style="text-align: center;">{{ $duplicates[$i]['topic']['id'] }}</td>
<td style="text-align: center;">{{ $duplicates[$i]['topic']['title'] }}</td>
<td style="text-align: center;">{{ $duplicates[$i]['total'] }}</td>
<td style="text-align: center;">{{ $choices[$i]['question_number'] }}</td>
<td><a class="btn btn-default" href="choices/{{ $choices[$i]['id'] }}/edit">Шинэчлэх</a></td>
</tr>
@endfor
The error you showed is from trying to access an array using object syntax:
{{ $choice->question_number }}
{{ $choice->question_number }}
$choices = Choice::where('user_id',Auth::id())->pluck('question_number');
$choices = Choice::where('user_id',Auth::id())->pluck('question_number');
If that is the only problem, then just don't use toArray() on the collection and leave it as an object or use array syntax.
In
foreach
that gives error like Array to string conversion
– Ruka Xing
Jul 3 at 2:22
foreach
Array to string conversion
view controller model ?
– Ruka Xing
Jul 3 at 2:24
please check my updated Question. @OneLiner
– Ruka Xing
Jul 3 at 2:29
Updated my answer. The crux of it is that you need to parse through one at the same rate as the other. As someone else mentioned though I think you should consider creating a relation in your model so you can have everything you need in one query. You should also use get() instead of pluck since you are using id and question_number.
– OneLiner
Jul 3 at 2:38
Let us continue this discussion in chat.
– OneLiner
Jul 3 at 2:40
1 solution
You are using the choice id in the blade file but on the query, you are not loading the id
So need to load the id and question_number both
$choices = Choice::where('user_id',Auth::id())->get(['id','question_number'])->toArray();
Also when you use toArray() you need to change the
From {{ $choice->question_number }}
{{ $choice->question_number }}
TO {{ $choice['question_number'] }}
{{ $choice['question_number'] }}
same for the choices edit link href="choices/{{ $choice['id'] }}/edit"
href="choices/{{ $choice['id'] }}/edit"
Or just remove the toArray()
from the query.
toArray()
2 solution
Now if you want to load the choice along with the topic and you have topic id in the choice model
$duplicates = Question::selectRaw("count('id') as total, topic_id")->with('topic', 'topic.choices')->groupBy('topic_id')->get(); // Id for this table is your question number or any realtion between the Question Model and Choice Model
$choices = Choice::where('user_id',Auth::id())->pluck('question_number','topic_id')->toArray();
return view('choices.index',compact('duplicates','choices'));
@foreach ($duplicates as $duplicate)
<tr>
<td style="text-align: center;">{{ $duplicate->topic->id }}</td>
<td style="text-align: center;">{{ $duplicate->topic->title }}</td>
<td style="text-align: center;">{{ $duplicate->total }}</td>
<td style="text-align: center;">
{{ isset($choices[$duplicate->topic->id]) ? $duplicate->topic->id : '' }}
</td>
<td>
<a class="btn btn-default" href="choices/{{ isset($choices[$duplicate->topic->id]) ? $choices[$duplicate->topic->id] : '' }}/edit">Шинэчлэх</a></td>
</tr>
@endforeach
i want to use 2 collection in 1 foreach. please help. then let me accept your answer.
– Ruka Xing
Jul 2 at 9:30
Yes you can. any realtion between the Question Model and Choice Model? It's seems that you have? It seems that it have with topic and then choice so topic hasOne realtion with choice or hasMany?
– DsRaj
Jul 3 at 4:30
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Please dump your variable before your loop starts and check the output. You can use laravel
dd($variable)
function to do this.– srimaln91
Jun 25 at 2:45