Items's avatar

Additional where clause triggers problem in the view

Hi, if I do this:

$withCentre = Event::with('centre')->where('centre_fk', $centreIdent)->orderBy("ev_date", "asc")->get();
$eventgroup = $withCentre->groupBy('centre_fk');

return view('pages.index')->with('eventgroup', $eventgroup);

everything works finde while iterating over $eventgroup in the view.

But when I use an additional where clause for the date:

$withCentre = Event::with('centre')->where('centre_fk', $centreIdent)->whereDate('ev_date', '>=', '2025-05-25')->orderBy("ev_date", "asc")->get();
$eventgroup = $withCentre->groupBy('centre_fk');

return view('pages.index')->with('eventgroup', $eventgroup);

I get an "Undefined array key 2" and it seems, that the where clause changes the object I work with in the view. But a dd($eventgroup) seems to deliver the same structure of the array with the same content. Or at least I can't find any difference in the collection that is passed to the view.

Has anybody an idea what goes wrong after inserting the where clause for the date?

Thanks in advance items :)

0 likes
23 replies
Items's avatar

It says: Internal Server Error ErrorException Undefined array key 2

 <tr>
        <th colSpan="5" class="
        p-2 pl-4 font-bold
       text-orange-800
       text-center">
           ** {{$events[$loop->iteration]->centre->name}}**
        </th>
      </tr>
        <tr class="bg-slate-400">
            @foreach($header as $head)
        <x-table-header :title="$head"/>
            @endforeach
      </tr>
    </thead>
    <tbody>
        @foreach($events as $event)
      <tr class="{{($loop->iteration) % 2 == 0 ? 'bg-gray-200' : 'bg-white'}}">

The bold part is the error part, so it seems that the object I iterate over is changed by the where clause. It works perfect without it.

Items's avatar

dd not working

dd working:

Snapey's avatar

It says: Internal Server Error ErrorException Undefined array key 2

No it doesn't it says a lot more than that, including the file and line the error occurred on.

Items's avatar

To me it seems that the where clause changes the object I iterate over. is this possible? dd seems to be exactly the same. In one case the array consists of one object and the working one has some more. But I can't find any other difference.

Snapey's avatar

So with the date filter, you only have one record.

How are you displaying them? With some sort of alternating display of records?

Glukinho's avatar

You pass variable $eventgroup to the view. Please show how it is transformed to $events (which you iterate with @foreach()) inside the view.

Items's avatar

Good morning and at first, thank you guys for your support! I've found the reason, but I've got no solution. Everything works fine with more than one record in the databse.

How do I work with the result set in the view:

// pass result to the view 
 return view('pages.index')->with('eventgroup', $eventgroup);

than I iterate by doing the following:

//Do I have a result at all?
@if(count($eventgroup))
// I have different events for different centres
@foreach($eventgroup as $events)
// Show the centres name
            {{$events[$loop->iteration]->centre->name}}
    ...
// Show the events title
            @foreach($header as $head)
        <x-table-header :title="$head"/>
            @endforeach
        @foreach($events as $event)
// show the events content
   <tr class="{{($loop->iteration) % 2 == 0 ? 'bg-gray-200' : 'bg-white'}}">
        <x-table-label content="{{$event->id}}"/>
        <x-table-label content="{{date_format(date_create($event->ev_date), 'd.m.Y')}}"/>
        <x-table-label content="{{$event->title}}"/>
        <x-table-label content="{{$event->destination}}"/>
    ...
       @endforeach
     @endforeach
// if no event for a centre is available show "No event"
  @else
  <div class="font-semibold flex justify-center p-6">
 No event
  </div>
  @endif

So mainly a simple things, I iterate over a collection of centres, and every centre consists of a collection of events.

It seems that the problem is not the where clause for the date, the problem is, that I pass a collection with just one event to the view. I will look to your hint with the index @snapey and I will compare the result again with one record (which fails) and 2 records (which works)

krisi_gjika's avatar

@Items

{{$events[$loop->iteration]->centre->name}} // <- why are you doing this outside the events loop
...
@foreach($events as $event)

why would the iteration count of the eventGroups be, in any reliable shape, related to the count/index of it's inner events? You basically say if I have X eventGroups, they must always also have at least X + 1 events inside.

1 like
Glukinho's avatar

It seems the problem is here:

@foreach($eventgroup as $events)
// Show the centres name
            {{$events[$loop->iteration]->centre->name}}

You iterate over $eventgroup but apply iteration counter $loop->iteration to the other variable $events.

In spite of $events can be an array, it may or may not have keys provided by $loop->iteration counter, that's why you sometimes get an error, sometimes don't.

Also @snapey is right, when you iterate with foreach, you should refer to the current item with the variable from foreach (in case of foreach($eventgroup as $events) it's $events) but not with loop counter, because loop counter always has values 1, 2, 3, ..., N, but iterated array can have various keys not necessarily going in a row.

1 like
Glukinho's avatar

@Items the error tells you: I want to get array item with key 1, but the array doesn't have this key.

dd tells you that your array (collection, to be precise) has only one item with key "buddha_house".

That is the problem.

1 like
JussiMannisto's avatar

@Items As @glukinho pointed out, you're using $loop incorrectly. You're iterating $eventgroup there, not $events, so $loop->iteration isn't related to $events.

But also: you can't use iteration like that. Iteration starts at 1, not 0. You must use index instead if you want to access an item.

1 like
JussiMannisto's avatar

@Items Just to make things clear, this part looks like it's in the wrong place. It's before the $events loop.

{{$events[$loop->iteration]->centre->name}}

I'd imagine the centre name should be inside the loop, so that it's shown for every event:

@foreach($events as $event)
	{{ $event->centre->name }}
	...
1 like
Items's avatar

The easiest and shortest way to solve it was this (the index doesn't work under other conditions):

 {{$events[0]->centre->name}}

I need the centre's name just one time for the table header and if the eventgroup is empty, I won't go into the loop. Seems to work in all combinations, so I can go back to my inital problem with the date now.

Finally it was a "loop" problem and not Eloquent, but I'm not able to change the title and topic. So sorry for leaving it, like it is.

Thanks a lot for your friendly patient and very helpful support!👋🙃

Snapey's avatar

You can also do this;

@foreach($eventgroup as $centerName => $events)

since the eventgroups are keyed by center name.

and then {{ $centerName }} where you want it in the output.

1 like
Ben Taylor's avatar

If you want to get rid of the if statement wrapper, you could do this.

@foreach($eventgroup ?? [] as $centerName => $events)
1 like
Snapey's avatar

or use @forelse

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse
1 like

Please or to participate in this conversation.