nomie
nomie

Reputation: 47

Nested foreach loop to show the data

I have 5 Models Purchase, Inventory, Slab, Scarting and FloorTile. I'm getting the collection from Purchase model, then from that collection i'm fetching data from Inventory table. Then depending on that data i going to further model Slab which has relation with Inventory. Now after getting data from the Slab model i want to show that on blade using Foreach loop. But i'm getting error:

Invalid argument supplied for foreach()

I've tried this in my Controller:

$slabs = Purchase::where('factoryName', $factoryName)->with('inventory.slab')->get();

This Query result is as follows:

{
    "id": 36,
    "marbleType_id": 2,
    "fname": "Sama",
    "lname": "Jojo",
    "factoryName": "Sama Inc.",
    "cnic": "3216542",
    "area": "Johar town",
    "city": "Lahore",
    "province": "Punjab",
    "phone1": "45678912345",
    "phone2": "45678912345",
    "inventory_ID": 10,
    "created_at": "2019-03-19 12:11:45",
    "updated_at": "2019-03-19 12:11:45",
        "inventory": {
        "id": 10,
        "purchase_id": 36,
        "marbleType": "1",
        "totalSquareFt": 25,
        "priceperSquareFt": 230,
        "totalPurchasePrice": 25000,
        "standardSize_ID": "5",
        "salePrice": 250,
        "miliMeter": "6mm",
        "slab_ID": 1,
        "scarting_ID": null,
        "floorTile_ID": null,
        "created_at": "2019-03-19 12:11:45",
        "updated_at": "2019-03-19 12:11:45",
            "slab": {
             "id": 1,
             "marbleName_ID": "2",
             "inventory_ID": "10",
             "created_at": "2019-03-19 12:11:45",
             "updated_at": "2019-03-19 12:11:45"
             }
        }
},
{
    "id": 55,
    "marbleType_id": 3,
    "fname": "Sama",
    "lname": "Jojo",
    "factoryName": "Sama Inc.",
    "cnic": "32165421",
    "area": "Johar town",
    "city": "Lahore",
    "province": "Punjab",
    "phone1": "45678912345",
    "phone2": "45678912345",
    "inventory_ID": 26,
    "created_at": "2019-04-25 10:47:41",
    "updated_at": "2019-04-25 10:47:41",
        "inventory": {
        "id": 26,
        "purchase_id": 55,
        "marbleType": "1",
        "totalSquareFt": 12,
        "priceperSquareFt": 12,
        "totalPurchasePrice": 120,
        "standardSize_ID": "1",
        "salePrice": 15,
        "miliMeter": "6mm",
        "slab_ID": 9,
        "scarting_ID": null,
        "floorTile_ID": null,
        "created_at": "2019-04-25 10:47:41",
        "updated_at": "2019-04-25 10:47:41",
            "slab": {
            "id": 9,
            "marbleName_ID": "3",
            "inventory_ID": "26",
            "created_at": "2019-04-25 10:47:41",
            "updated_at": "2019-04-25 10:47:41"
            }
        }
},
{
    "id": 56,
    "marbleType_id": 4,
    "fname": "Sama",
    "lname": "Jojo",
    "factoryName": "Sama Inc.",
    "cnic": null,
    "area": "Johar town",
    "city": "Lahore",
    "province": "Punjab",
    "phone1": "45678912345",
    "phone2": "45678912345",
    "inventory_ID": 27,
    "created_at": "2019-05-05 20:11:52",
    "updated_at": "2019-05-05 20:11:52",
        "inventory": {
        "id": 27,
        "purchase_id": 56,
        "marbleType": "3",
        "totalSquareFt": 20,
        "priceperSquareFt": 20,
        "totalPurchasePrice": 420,
        "standardSize_ID": "3",
        "salePrice": 25,
        "miliMeter": "6mm",
        "slab_ID": null,
        "scarting_ID": null,
        "floorTile_ID": 10,
        "created_at": "2019-05-05 20:11:52",
        "updated_at": "2019-05-05 20:11:52",
        "slab": null
        }
},
{
    "id": 57,
    "marbleType_id": 9,
    "fname": "Sama",
    "lname": "Jojo",
    "factoryName": "Sama Inc.",
    "cnic": null,
    "area": "Johar town",
    "city": "Lahore",
    "province": "Punjab",
    "phone1": "45678912345",
    "phone2": "45678912345",
    "inventory_ID": 28,
    "created_at": "2019-05-05 20:32:41",
    "updated_at": "2019-05-05 20:32:41",
        "inventory": {
        "id": 28,
        "purchase_id": 57,
        "marbleType": "2",
        "totalSquareFt": 31,
        "priceperSquareFt": 12,
        "totalPurchasePrice": 400,
        "standardSize_ID": "1",
        "salePrice": 15,
        "miliMeter": "8mm",
        "slab_ID": null,
        "scarting_ID": 4,
        "floorTile_ID": null,
        "created_at": "2019-05-05 20:32:41",
        "updated_at": "2019-05-05 20:32:42",
        "slab": null
        }
},
{
    "id": 59,
    "marbleType_id": 12,
    "fname": "Sama",
    "lname": "Jojo",
    "factoryName": "Sama Inc.",
    "cnic": null,
    "area": "Johar town",
    "city": "Lahore",
    "province": "Punjab",
    "phone1": "12345678945",
    "phone2": "45678945645",
    "inventory_ID": 30,
    "created_at": "2019-05-06 10:14:35",
    "updated_at": "2019-05-06 10:14:35",
        "inventory": {
        "id": 30,
        "purchase_id": 59,
        "marbleType": "2",
        "totalSquareFt": 12,
        "priceperSquareFt": 12,
        "totalPurchasePrice": 122,
        "standardSize_ID": "1",
        "salePrice": 12,
        "miliMeter": "8mm",
        "slab_ID": null,
        "scarting_ID": 5,
        "floorTile_ID": null,
        "created_at": "2019-05-06 10:14:35",
        "updated_at": "2019-05-06 10:14:35",
        "slab": null
        }
}

Here is the Foreach loop in the controller to get data only related to Slab.

foreach ($slabs as $slab) {
   if ($slab->inventory->slab_ID != NULL) {
       $marble_id = $slab->inventory->slab->marbleName_ID;
       $slab->marble = MarbleType::where('id', $marble_id)->get();
   }
}

And here is the blade content where I want to show Slab's data in the table.

@foreach($slabs  as $slab)
    @foreach($slab->marble as $mar)
        <tr>
            @if($slab->inventory->marbleType == 1)
               <td> Slab </td>
            @endif
            <td>{{ $mar->marbleType }}</td>
            <td>{{ $slab->inventory->totalSquareFt }}</td>
            <td>{{ $slab->inventory->totalPurchasePrice }}</td>
            <td>{{ date('M j, Y h:ia' , strtotime( $slab->created_at )) }}</td>
        </tr>
    @endforeach    
@endforeach

This the error i'm getting on the blade file: Invalid argument supplied for foreach()

Can anyone point out what i'm doing wrong.?

Upvotes: 1

Views: 410

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29258

You probably need an else statement on your $slab->inventory->slab_ID check, otherwise, you'll be trying to loop null ($slab->marble will equate to null). If you did else { $slab->marble = []; }, then you'd be able to use that foreach without worry code.

foreach ($slabs as $slab) {
  if ($slab->inventory->slab_ID != NULL) {
    $marble_id = $slab->inventory->slab->marbleName_ID;
    $slab->marble = MarbleType::where('id', $marble_id)->get();
  } else {
    $slab->marble = [];
  }

  foreach($slab->marble AS $mar){
    ...
  }
}

Sidenote, this code is likely very inefficient. Anytime you need to run a query in a loop, you face the potential for a bottleneck. Consider using a relationship and eager loading that in your initial query.

Also sidenote, if $slab->inventory is null, you'll run into a trying to get property of non-object error when using $slab->inventory->slab_ID.

Upvotes: 1

Related Questions