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

eggplantSword's avatar

Map on query not working as expected, ignoring variable

This is my query

Team::with('user', 'teamUsers.user:id,name')->whereHas('teamUsers.route')->get()
            ->map(function($item) {
                $return[] = ['value' => $item->user->id, 'label' => $item->user->name];

                $item->teamUsers->each(function ($v) use ($return) {
//problem here
                    $return[] =  ['value' => $v->user_id, 'label' => $v->user->name];
                });

                return $return;
            })->collapse()
result
[{"value":1,"label":"Super Admin"}]

The issue is that the each is being ignored when I know there is data in there. the $result[] throws this message Unused local variable 'return'. The value of the variable is not used anywhere. so it never gets updated for some reason.

If I do this instead

$return[] = $item->teamUsers->each(function ($v) use ($return) {
                    return ['value' => $v->user_id, 'label' => $v->user->name];
                });
result
[{"value":1,"label":"Super Admin"},[{"id":1,"team_id":1,"user_id":2,"created_at":null,"updated_at":null,"user":{"id":2,"name":"Test"}},{"id":2,"team_id":1,"user_id":3,"created_at":"2023-02-16T21:10:59.000000Z","updated_at":"2023-02-16T21:10:59.000000Z","user":{"id":3,"name":"asdf"}}]]

The result I want

[{"value":1,"label":"Super Admin"}, {"value":2,"label":"User"}, {"value"3,"label":"Other User"}]

How can I fix this?

EDIT: if I change to using a collection instead of an array it works, why?

Team::with('user', 'teamUsers.user:id,name')->whereHas('teamUsers.route')->get()
            ->map(function($item) {
                $return = collect();
                $return->push(['value' => $item->user->id, 'label' => $item->user->name]);

                $item->teamUsers->each(function ($v) use ($return) {
                    $return->push(['value' => $v->user_id, 'label' => $v->user->name]);
                });

                return $return;
            })->collapse()
0 likes
4 replies
webrobert's avatar

its not ignored its not passed. you need to use map and return if you want to get back the result there

webrobert's avatar

edit: because each doesn't maintain the return variable

eggplantSword's avatar

@webrobert I originally tried using map but had the same result so I tried with each, but if each doesn't maintain the return variable how come in when I change from array to collection it works?

webrobert's avatar

@msslgomez

Team::with('user', 'teamUsers.user:id,name')->whereHas('teamUsers.route')->get()
  ->flatMap( fn($item) => [
    ['value' => $item->user->id, 'label' => $item->user->name],
    ...$item->teamUsers->map(fn ($v) => ['value' => $v->user_id, 'label' => $v->user->name])
 ]);

here is a fun alternative.. its close to working, or it does... one of the maps may need to be changed to flatMap or vs versa.

Please or to participate in this conversation.