0

I am following a shopping cart tutorial with Laravel, but even though I've copied his code to the point, it does not work like on the tutorial. Every time you click on a product, the shopping cart quantity SHOULD increment, but it didn't.

I am following the tutorial of Max Schwarzmueller's "Laravel Shopping Cart" which you can find on youtube at: https://www.youtube.com/watch?v=56TizEw2LgI&list=PL55RiY5tL51qUXDyBqx0mKVOhLNFwwxvH. I am stuck at #8.

I am new with php, laravel and sessions. I've tried using facades (e.g. Session::put) instead of "$request->session()->put('cart', $cart)". Printing the session with "dd(session()->all())" does confirm that the correct item got added to the array shopping cart.

In ProductController.php

<?php

namespace App\Http\Controllers;

use Session;
use App\Http\Controllers;
use App\Product;
use App\Cart;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function getIndex()
    {
        $products = Product::all();
        return view('shop.index', ['products' => $products]);
    }

    public function getAddToCart(Request $request, $id){
        $product = Product::find($id);

        //check in session if cart already contains product
        $oldCart = Session::has('cart') ? Session::get('cart') : null;

        //if it did contain products, pass them to constructor
        $cart= new Cart($oldCart);

        $cart->add($product, $product->id);

        $request->session()->put('cart', $cart);
        Session::save();

        return redirect()->route('product.index');
    }
}

In Cart.php

<?php

namespace App;

use Session;

class Cart 
{
    public $items = Array();
    public $totalQty = 0;
    public $totalPrice = 0;

    public function _construct($oldCart){
        if($oldCart){
            $this->items = $oldCart->items;
            $this->totalQty = $oldCart->totalQty;
            $this->totalPrice = $oldCart->totalPrice;
        }
    }

    public function add($item, $id) {
        //default values if item not in cart 
        $storedItem = [
            'qty' => 0,
            'price' => $item->price,
            'item' => $item
        ];

        //if item is already in shopping cart
        if($this->items) {
            if(array_key_exists($id, $this->items) ) {
                $storedItem = $this->items[$id];
            }
        }

        $storedItem['qty']++;
        $storedItem['price'] = $item->price * $storedItem['qty'];
        $this->items[$id] = $storedItem;
        $this->totalQty++;
        $this->totalPrice += $item->price;
    }
}

Every time I click on product it activated the getAddtoCart function of ProductController

<a href="{{ route('product.addToCart', ['id'=> $product->id]) }}">Order</a>

I expect that the totalQty of shopping cart should be incremented every time I click on "order" of every products. If I click twice on "order" for Poke Ball, the "qty" for this specific item (with id 1) should also increment.
But the totalQty starts from 0, but does not increment more than 1. Also qty for the specific item remains 1.

CindyK
  • 3
  • 3
  • Have you tried dumping the full session to see if something about the cart is updated? – Mtxz Aug 19 '19 at 19:13
  • @Mtxz . I used the "dd(session()->all()", if that is what you mean. If I click on Poke Ball, it is shown in the array "items", but if I click on Great Ball, it shows only this item in the array; as if Poke ball has not been clicked before. – CindyK Aug 19 '19 at 19:23
  • You shouldn't have to call `Session::save()` in order to save the session data. I'm wondering if you're having trouble with your sessions and the data is not being persisted. Are you sure you're not calling `dd(...)` anywhere during the request which would prematurely end the request and prevent the session data from persisting? Can you confirm that you can persist _any session data_ at all? – waterloomatt Aug 20 '19 at 00:27
  • What session driver are you using? _file_? If you're not sure, take a look at `config/session.php`. Finally, try clearing your browser cache and cookies. – waterloomatt Aug 20 '19 at 00:33
  • @waterloomatt . I've removed the `Session::save()`, thanks for the info. I've checked, and nowhere else did I have the `dd()` . Session driver is `'driver' => env('SESSION_DRIVER', 'file'),` which indeed creates a file inside my storage sessions folder. Clearing browser cache and cookies did not help. The quantity does reset to 0, and if I click on "order", it does increment to 1, but it will not get higher than 1 no matter how often I click on "order" again – CindyK Aug 20 '19 at 07:35

1 Answers1

0

Took me a while to find this but it turns out to be a simple syntax error that is throwing everything off. Your cart's constructor is defined with a single underscore and should be defined using double-underscore.

Since PHP doesn't require the use of a constructor, your code to merge the old/new carts simply wasn't running. https://stackoverflow.com/a/455929/296555

// Wrong
public function _construct($oldCart){
   ...
}

// Right
public function __construct($oldCart){
   ...
}
waterloomatt
  • 3,662
  • 1
  • 19
  • 25