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

waleedviews's avatar

How to search value in collection and merge model in laravel

I have 2 arrays and each array has deeply nested array below is the array

$invoices = $request->user()->invoices();
0 => array:74 [▼
    "id" => "in_1MPwwCGBXoaOj5Wmk7lPY9tJ
    "lines" => array:5 [▼
      "object" => "list"
      "data" => array:2 [▼
        0 => array:24 [▶]
        1 => array:24 [▶]
      ]
      "has_more" => false
      "total_count" => 2
      "url" => "/v1/invoices/"
    ]
1 => array:74 [▼
    "id" => "in_1MPwwCGBXoaO22vWmk7lPY9tJ
    "lines" => array:5 [▼
      "object" => "list"
      "data" => array:2 [▼
        0 => array:24 [▶]
        1 => array:24 [▶]
      ]
      "has_more" => false
      "total_count" => 2
      "url" => "/v1/invoices/"
    ]

i am trying to get the id from the deep nested array like this

$productnames = $invoices->first()->lines->first()->id;

and then search for the id in the modal like this

    $plans = Plan::where('stripe_id', $productnames)->first();

it only display one id, and not all the id from the array,

also, when i merge both the collection it shows result like the below

    $invoicescollection = new Collection($invoices);
    $planscollection = new Collection($plans);
    $products = $invoicescollection->merge($plans)->toArray();

    array:10 [▼ // app/Http/Controllers/Billing/BillingController.php:26
      0 => array:74 [▶]
      1 => array:74 [▶]
      "id" => 5
      "title" => "All"
      "slug" => "all"
      "stripe_id" => "price_1MO55aOGBXoaOjvWmuQCJ14b3"
      "active" => "0"
      "created_at" => null
      "updated_at" => null
    ]

i wanted to show the merge data in each array, not like the above.

thank you for the help.

0 likes
32 replies
webrobert's avatar

for the first part I think you want pluck https://laravel.com/docs/9.x/collections#method-pluck

not sure of the exact path but

$productnames = $invoices->pluck('lines.id');

then you want whereIn not where

    $plans = Plan::whereIn('stripe_id', $productnames)->first();

but that first only will give you the first row. so you probably want...

    $plans = Plan::whereIn('stripe_id', $productnames)->get();
webrobert's avatar

and another goodie is higher order map.

You can do $invoices->map->lines and get all the lines from the invoices.

 $invoices->map->lines->pluck('id')
1 like
waleedviews's avatar

@webrobert thank you for the reply, i have a nested array

$database = collect($invoices)->map->lines->map->data;

the data has a price array, when i fetch the price through mapping it shows error

Undefined array key "price"

$database = collect($invoices)->map->lines->map->data->map->price->id;

in case you wanted to look into array i attached screenshot. https://www.dropbox.com/s/u6fgp3ctz0rxqah/error.png?dl=0

webrobert's avatar

and What about this

$invoices->map(fn ($item) => $item->lines->data)->toArray()
webrobert's avatar

@waleedviews, ok what do you want? do you want the ids for ALL those items?

$invoices->flatMap(fn ($item) => $item->lines->data)->pluck('id')

or something else?

webrobert's avatar

@waleedviews also

...you are fetching data->id

no, the flatMap should return a list of lines. it flattens out the array of arrays. then it should be returning the item id.

$invoices->flatMap(fn ($item) => $item->lines->data)->pluck('id')

any who.

1 like
numaan's avatar

To get all the ids from the deep nested array, you can use the map method on the data array:

$productnames = $invoices->first()->lines->data->map(function($line) {
    return $line->id;
});

Then you can use the whereIn method to search for all the ids in the modal:

$plans = Plan::whereIn('stripe_id', $productnames)->get();

Regarding the merging of the collections, you're currently merging the entire $plans collection into the $invoicescollection collection. Instead, you can iterate over the $invoices collection and merge the corresponding plan into each invoice. Here's an example of how you could do this:

$invoices = $request->user()->invoices();
$invoices = $invoices->map(function($invoice) {
    $productnames = $invoice->lines->data->map(function($line) {
        return $line->id;
    });
    $plans = Plan::whereIn('stripe_id', $productnames)->get();
    return array_merge($invoice->toArray(), ['plans' => $plans->toArray()]);
});

This will add a new key plans to each invoice array, containing the corresponding plans.

It's also worth noting that you don't need to create a new Collection objects, since $invoices is already a collection, and Laravel collection are immutable, so you can chain the map method in the same way.

1 like
webrobert's avatar

thanks @numaan, now that we just did all that work.

@waleedviews did you just want the price->id for the first invoice?

then dont use flatMap

$invoices->first()
   ->map( fn ($item) => $item->lines->data)->pluck('price.id')
1 like
waleedviews's avatar

@webrobert i want to fetch all the price->id, your help have resolved alot of my issues, thank you so much for your precious time, the only help i need with merging the arrays now.

webrobert's avatar

@waleedviews of course. This is getting the ids you want, yes?

$invoices->flatMap( fn ($item) => $item->lines->data)->pluck('price.id')
1 like
waleedviews's avatar

@webrobert yes this was helpful, now i want to merge plans into each invoice array, very near to resolve the issue.

webrobert's avatar

@waleedviews

Not sure that I follow. I thought we just got ALL the price.ids from all the invoices. not one... OR are you actually getting all the price.ids within each invoice?

webrobert's avatar
$invoices = $request->user()->invoices()
  ->map( function($invoice) {
      $priceIds = collect($invoice->lines->data)->pluck('price.id');

      $invoice['plans'] = Plan::whereIn('stripe_id', $priceIds)->get();

      return $invoice;
  });
waleedviews's avatar

@webrobert very near, this is giving me an error

Call to undefined method Laravel\Cashier\Invoice::map()
waleedviews's avatar

@webrobert another error

Cannot use object of type Laravel\Cashier\Invoice as array

this is generating an error

$invoice['plans'] = Plan::whereIn('stripe_id',  $priceIds)->get();
webrobert's avatar
Level 51

@waleedviews wait, what...

$invoices = $request->user()->invoices()
  ->map( function($invoice) {
      $priceIds = collect($invoice->lines->data)->pluck('price.id');

	  dd($priceIds);

      $invoice['plans'] = Plan::whereIn('stripe_id', $priceIds)->get();

      return $invoice;
  });
webrobert's avatar

@waleedviews

I think we are off in the weeds a bit. I didn't realize this was cashier. I imagine there is a cleaner way to do what you are after. Unfortunately, I have to disband. Now. I think its close to working. Just back it out. The original code we wrote was to get all the price ids from all the invoices.

this bit...

$invoices->flatMap( fn ($item) => $item->lines->data)->pluck('price.id')

and that works.

but what you actually want is to get the price ids for each invoice and include them with the invoice, correct?

I imagine there is a way to query for this with Cashier.

waleedviews's avatar

@webrobert your help have resolved alot of my issue, i have fix the code, thank you so much for the help. God bless you sir.

1 like

Please or to participate in this conversation.