Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kejpa's avatar
Level 1

@foreach loops more times than the query answers

Hi, just getting started and the first view is making me have second thoughts about Laravel... I have a query which returns three rows (I echoed the sql and run it my self) but when I do a @foreach on the result it loops far too many times (22!) And I can't use the loop variable for showing the result, when I try I get an "Undefined property" error no matter what I write :(

Help, please! /Kjell

0 likes
10 replies
bobbybouwmann's avatar

Show your controller and view code please! We can help you with more information ;)

If you loop over a single object it will return an array of all properties and you will have more fields than expected probably!

36864's avatar

You'll have to post your code so we can see what's going on.

Specifically, your view and controller.

jlrdw's avatar

Help, please!

Show code please!

1 like
kejpa's avatar
Level 1

My route: Route::get('/bok/{id}', function ($id) {

$info= Book::findOrFail($id);

if ($info->isbn=="") {
    $books= DB::table('books')
            ->select('id, 'inventorynumber')
            ->where('title','=',$info->title);
} else {
    $books= DB::table('books')
            ->select('id', 'inventorynumber')
            ->where('isbn','=',$info->isbn);
}

return view('books.show1')->with(['book'=> $info, 'books'=>$books]);

})->where('id' , '\d+');

My view (simplified) @section ('content')

  • {{ $book->title }}
  • {{ $book->author }}
  • {{ $book->isbn }}
@foreach($books as $ex)
  • {{ $ex->id}}
  • {{ $ex->inventorynumber}}
@endforeach @stop

Changing $ex to $book will make the view work and returns 22 rows, when the sql returns one. When I chose another id I will still get 22 loops even though that sql returns 3 rows

Cronix's avatar
Cronix
Best Answer
Level 67

I don't even see how your code works at all. You never actually execute the query to get $books in your controller. You do for $info (which is one book). You're also missing quotes in places

Does this work?

$info= Book::findOrFail($id);

if ($info->isbn=="") {
    $books = DB::table('books')
            ->select('id', 'inventorynumber')
            ->where('title','=',$info->title)
            ->get();
} else {
    $books = DB::table('books')
            ->select('id', 'inventorynumber')
            ->where('isbn','=',$info->isbn)
            ->get();
}

return view('books.show1')->with(['book'=> $info, 'books'=>$books]);
1 like
Cronix's avatar

Also, what version of laravel are you using? You have @stop in your template. I believe that was deprecated with version 5, and replaced with @endsection

Cronix's avatar

You're welcome! Please mark the post as solved.

You could also shorten it a bit

$info= Book::findOrFail($id);

$bookQuery = DB::table('books')->select('id', 'inventorynumber');

if ($info->isbn=="") {
    $bookQuery->where('title','=',$info->title);
} else {
    $bookQuery->where('isbn','=',$info->isbn);
}

$books = $bookQuery->get();

return view('books.show1')->with(['book'=> $info, 'books'=>$books]);
1 like
kejpa's avatar
Level 1

Great! DIdn't realize that you could do like that. I'll remove the redundant code!

Thanks again! /Kjell

Cronix's avatar

You can build on the query builder instance up until you execute it. I just put the common parts of the query first, and added the where clause to it separately, and then executed the query with ->get() after everything was put together.

1 like

Please or to participate in this conversation.