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





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


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.

Popular posts from this blog

Rothschild family

Cinema of Italy