Trying to get property 'images' of non-object (View: C:\wamp\www\site\resources\views\site\pages\cart.blade.php)

cart.blade.php:

@forelse ($items as $item)
                                        @php
                                            $product = isset($item->associatedModel->parent) ? $item->associatedModel->parent : $item->associatedModel;
                                            $image = !empty($product->images->first()) ?  asset('storage/'.$product->images->first()->full)  : 'https://via.placeholder.com/176'
                                        @endphp
                                    <tr>
                                    <td class="product-thumbnail">
                                                <a href="{{ route('product.show', $product->slug) }}"><img src="{{ $image }}" alt="{{ $product->name }}" style="width:100px"></a>
                                            </td>

cartcontroller:

 public function getCart()
    {

        $items = \Cart::getContent();

        return view ('site.pages.cart',compact('items'));
    }

Ce que je veux

image,nom,... dans la page cart

Ce que j'obtiens

j'obtiens Trying to get property 'images' of non-object
donc s'il vous plait comment resoudre ça et merci

3 réponses


Salut

Alors il faut remplacer !empty($product->images->first()) par exists:

!$product->images->exists()

En gros il n'y a pas d'images, et Laravel essayes de récupérer le premier élément images (qui n'existe pas) et essaye de vérifier à l'intérieur pour voir si son contenu est vide, mais comme le contenant n'existe pas, ça fait erreur

La function empty ne sert pas à vérifier si une entité existe, mais part du principe que l'entité existe et vérifie si elle est vide :)

finan
Auteur

merci popotte pour la réponse

avec cet code il marche et ne donne pas l'erreur:

public function store(Request $request)
    {
        $params = $request->except('_token');

        $product = Product::findOrFail($params['productId']);
        $slug = $product->slug;

        $attributes = [];

        $itemQuantity =  $this->_getItemQuantity(md5($product->id)) + $params['qty'];
        $this->_checkProductInventory($product, $itemQuantity);

        $item = [
            'id' => md5($product->id),
            'name' => $product->name,
            'price' => $product->price,
            'quantity' => $params['qty'],
            'attributes' => $attributes,
            'associatedModel' => $product,
        ];

        \Cart::add($item);

        return redirect('/product/'. $slug)->with('message', 'Product '. $item['name'] .' has been added to cart');
    }

mais je veut l'essayer avec cet code dans productController comme ça

 public function addToCart(Request $request)
    {
        $params = $request->except('_token');
        $product = $this->productRepository->findProductById($request->input('productId'));

        $options = $request->except('_token', 'productId', 'price', 'qty');

        Cart::add(uniqid(),  $product->name, $request->input('price'), $request->input('qty'), $options);

        return redirect()->back()->with('message', 'Item added to cart successfully.');

    }

donc comment modifier $product sans $item->associatedModel dans le cart.blade.php:

    @php
                                            $product = isset($item->associatedModel->parent) ? $item->associatedModel->parent : $item->associatedModel;
                                            $image = !empty($product->images->first()) ?  asset('storage/'.$product->images->first()->full)  : 'https://via.placeholder.com/176'
                                        @endphp

et merçi beaucoup

Alooors, c'est un peu spécial la façon de faire, normalement sur Laravel on utlise Eloquent/save() et des Relations, mais vu le code tout le système que propose Laravel n'est pas en place donc bon on va laisser comme ça pour l'instant x)

Si tu veux utiliser la façon "Laravel" de faire, il faut que tu ajoutes un champ cart_id dans la table products:

databases/migrations/12345689_create_products_table.php

$this->foreignId('cart_id')
      ->constrained()
      ->onUpdate('cascade')
      ->onDelete('cascade');

Et que tu fasses les relations à partir du model:

Cart:

public function products(): HasMany
{
    return $this->hasMany(Product::class);
}

Product:

public function cart(): BelongsTo
{
    return $this->belongsTo(Cart::class);
}

A partir de la tu pourras virer Cart::add()utiliser du Eloquent :p

Fin de la parenthèse

Pour la vue, alors ce serait comme ça:

@php
    $product = $item->associatedModel->parent ?? $item->associatedModel; // $item->associatedModel->parent si ça existe, sinon $item->associatedModel
    $image = $product->images->exists() ?  asset('storage/'.$product->images->first()->full)  : 'https://via.placeholder.com/176'
@endphp

Maintenant en vrai ce code ne devrait pas se trouver dans la vue, il devrait etre dans le ->with([]) du controller:

return view('')->with([
    "product" => $item->associatedModel->parent ?? $item->associatedModel, // $item->associatedModel->parent si ça existe, sinon $item->associatedModel
    "image" => $product->images->exists() ?  asset('storage/'.$product->images->first()->full)  : 'https://via.placeholder.com/176'
]);

// ou

return redirect()->back()->with([...]);

En gros il y a un principe dans Laravel et PHP: Il faut seulement dire à la vue d'afficher les données, faut rien demander à la vue, on demande tout au controller, et le controller donne à la vue les données à afficher, la vue affiche sans réfléchir ^^