0

I'm in the beginning stages of trying to make sense of Laravel and am having trouble displaying the 'illuminate collection object' passed to a blade from a controller.

My print_r is outputting "Illuminate\Support\Collection Object ( [items:protected] => Array ( ) ) 1" which I thought meant that it was seeing one item in the array (just one record in the table currently), but I'm hitting the @else statement so I'm guessing it's actually empty. I'm getting no errors, but I have not been able to display anything from $products despite $title outputting just fine.

public function shop(){
        $products = DB::table('products')->get();
        $data = array(
            'title'=>'Shop',
            'products' => $products
        );
        return view('pages.shop')->with($data);
    }
@section('content')
    <h1>{{$title}}</h1>
    {{ print_r($products) }}
    @if($products->count())
        <ul class="list-group">
            @foreach($products as $product)
                <li class="list-group-item">{{$product->title}}</li>
            @endforeach
        </ul>
    @else
        <p>No products</p>
    @endif
@endsection

Why is my array empty?

V1xIII
  • 169
  • 1
  • 4
  • 14
  • You need to output the column name for the product in the list-group-item like {{ $product->name }} – Mike May 23 '19 at 21:04
  • Nope, still nothing. I put an @if(count($products)) in there and it's hitting the @else statement, so apparently there is nothing in the array? – V1xIII May 23 '19 at 21:09
  • So Eloquent queries will return a Collection class that acts like an array of all your rows as eloquent models. So count($products) may not work, but $products->count() will work. Check out https://laravel.com/docs/5.8/eloquent-collections for more on the Collection class. Anyway in your controller before you return the view, what do you see if you dd($products); ? – Mike May 23 '19 at 21:12
  • Collection {#215 ▼ #items: [] } – V1xIII May 23 '19 at 21:14
  • So it looks like you aren't getting any results then right? – Mike May 23 '19 at 21:16
  • Looks that way to me – V1xIII May 23 '19 at 21:17
  • Also just realized you are using the DB class not eloquent, but either way, make sure there is data in your database, and your connection settings are correct. – Mike May 23 '19 at 21:19
  • I migrated and seeded with my current settings, so I'm guessing so. I'll have a look into the DB vs eloquent situation. – V1xIII May 23 '19 at 21:22
  • Just curious if you figured out the issue? – Mike May 24 '19 at 22:03
  • It was related to the blade end of things actually, according to the guy with the accepted answer. He deleted that comment though. – V1xIII May 30 '19 at 14:45

5 Answers5

1

On your Controller:

$title = 'Shop';
$products = DB::table('products')->get();

return view('pages.shop', compact('title', 'products');

On your Blade:

I would also suggest to put your unordered list tag <ul> outside of the loop then use @forelse for a cleaner code, like so:

@section('content')
  <h1>{{$title}}</h1>
  <ul class="list-group">
    @forelse($products as $product)
       <li class="list-group-item">{{$product->title}}</li>        
    @empty
       <li class="list-group-item">No products</li>  
    @endforelse
  </ul>
@endsection
kapitan
  • 2,008
  • 3
  • 20
  • 26
  • This did the trick. I guess it had to do with using "with" instead of "compact"? Also, thanks for the heads up on the forelse loop! – V1xIII May 26 '19 at 18:37
1

Try this..........

public function shop()
    {
        $products   = DB::table('products')->get();
        $title      = "Shop";
        return view('pages.shop', compact('products', 'title'));
    }

@section('content')
    <h1>{{ isset($title) ? $title : '-' }}</h1>
    @if($products->count())
        <ul class="list-group">
            @foreach($products as $product)
                <li class="list-group-item">{{ isset($product->title) ? $product->title : '-' }}</li>
            @endforeach
        </ul>
    @else
        <p>No products</p>
    @endif
@endsection
0

You can display the data by first passing it as an array to the view

return view('pages.shop')->with('data', $data);

then in the blade

@section('content')
    <h1>{{$data['title']}}</h1>
    @if(count($data['products']))
        <ul class="list-group">
            @foreach($data['products'] as $product)
                <li class="list-group-item">{{$product->title}}</li>
            @endforeach
        </ul>
    @else
        <p>No products</p>
    @endif
@endsection
Aditya Thakur
  • 2,562
  • 2
  • 10
  • 21
0

Pass both $products and $title to the view, I prefer to use compact feels cleaner.

$title = 'shop';
$products = DB::table('products')->get();


return view('pages.shop', compact('title', 'products');

Then in your view you can reference them directly. As you are doing now.

@section('content')
    <h1>{{$title}}</h1>

    @if($products->count())
        <ul class="list-group">
            @foreach($products as $product)
                <li class="list-group-item">{{$product->title}}</li>
            @endforeach
        </ul>
    @else
        <p>No products</p>
    @endif
@endsection
Dave
  • 878
  • 8
  • 19
0

In your controller

$title = 'shop';
$products = DB::table('products')->get();
return view('pages.shop', compact('title', 'products');
OR
$products = DB::table('products')->get();
$data = array(
        'title'=>'Shop',
        'products' => $products
);
return view('pages.shop')->with('data',$data);

In your Blade

@section('content')
<h1>{{$title}}</h1>
@if(count($products))
    <ul class="list-group">
        @foreach($products as $product)
            <li class="list-group-item">{{$product->title}}</li>
        @endforeach
    </ul>
@else
    <p>No products</p>
@endif
@endsection
Jithesh Jose
  • 1,781
  • 1
  • 6
  • 17