0

i'm currently working on a webshop that's all about different types of hair colors, but i kinda have an issue right now. I'm working on a button that automatically deletes one product from a session file. For that i'm using a $request->session()->forget('cart'); line.

This is what my controller looks like:

public function index()
{
    // Dit zorgt ervoor dat alle producten in het tabel Product-
    // opgehaald worden en in de variabele $products gezet worden

    $products = Product::all();

    return view('winkelmand', compact('products'));
}

/**
 * Show the form for creating a new resource.
 *
 * @return void
 */
public function create()
{
    return false;
}

/**
 * Store a newly created resource in storage.
 *
 * @param \Illuminate\Http\Request $request
 * @return Application|Factory|View
 */
public function store(Request $request)
{
    $product = Product::find($request->id);
    if (!$product) {
        abort(404);
    }
    $id = $request->id;

    $cart = session()->get('cart');
    // Als het winkelwagendje leeg is, dan is dit het eerste product
    if (!$cart) {
        $cart = [
            $id => [
                "name" => $product->name,
                "description" => $product->description,
                "price" => $product->price,
                "quantity" => 1
            ]
        ];

        session()->put('cart', $cart);

        return view('winkelmand');
    }

    // Als het product al bestaat, dan de quantiteit verhogen met 1
    if (isset($cart[$id])) {
        $cart[$id]['quantity']++;
        session()->put('cart', $cart);

        return view('winkelmand');
    }
    // Als het product niet bestaat dan toevoegen met quantiteit = 1
    $cart[$id] = [
        "name" => $product->name,
        "price" => $product->price,
        "description" => $product->description,
        "quantity" => 1
    ];

    session()->put('cart', $cart);

    return view('winkelmand');
}

/**
 * Display the specified resource.
 *
 * @param Request $request
 * @param int $id
 * @return Application|Factory|View
 */
public function show(Request $request, $id)
{
    return false;
}


/**
 * Show the form for editing the specified resource.
 *
 * @param int $id
 * @return \Illuminate\Http\Response
 */
public function edit($id)
{
    return false;
}

/**
 * Update the specified resource in storage.
 *
 * @param \Illuminate\Http\Request $request
 * //     * @param int $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request)
{
    if ($request->id && $request->quantity) {
        $cart = session()->get('cart');

        $cart[$request->id]["quantity"] = $request->quantity;

        session()->put('cart', $cart);
        session()->flash('success', 'Cart updated successfully');
    }
}

/**
 * Remove the specified resource from storage.
 *
 * //     * @param int $id
 * @return string
 */
public function destroy(Request $request)
{
    //Deze functie moet ervoor zorgen dat er door middel van een knop de
    // desbetreffende item verwijderd wordt uit het winkelwagentje.
    // Deze functie werkt alleen nog niet en wordt dus niet gebruikt in de webshop

    $request->session()->forget('cart');
    dd('cart');

    return view('winkelmand');
}

I added a button using a form and method POST to the HTML:

<td>
    <form action="/winkelmand/{{ $id }}" method="POST">
        @csrf
        <input name="_method" type="hidden" value="delete" />
        <input type="submit" value="x" />
    </form>
</td>

So it's supposed to retrieve one specific product from the session (from whatever product button is pressed) and then it's supposed to forget that key from a session.

Anybody who can help me with that?

Ps. Sorry for my vocabulary.

Isaac Bennetch
  • 11,830
  • 2
  • 32
  • 43

1 Answers1

0

You never shared what the issue is. Is it not working ? Based on your code, I am assuming you are getting perma 404.

Some tips:

  • No need to do abort(404), you can directly use findOrFail($request->id).
  • No need to do findOrFail when you can take advantage of Implicit Binding.
  • No need to write <input name="_method" type="hidden" value="delete" />, you can directly do @method('DELETE').

I assume your problem is that you are using $request->id but you are never sending id. You have id in the URL, but for your code to work, you should do:

/**
 * Store a newly created resource in storage.
 *
 * @param \Illuminate\Http\Request $request
 * @return Application|Factory|View
 */
public function store(Request $request, $id)
{
    $product = Product::findOrFail($id);

Remember to replace this part of the code with mine above:

public function store(Request $request)
{
    $product = Product::find($request->id);
    if (!$product) {
        abort(404);
    }
    $id = $request->id;

This still looks for the product to exists (no random ids). Then get the cart, find if the id exists in that cart and unset it (delete it), save the cart again, and done.

public function destroy(Request $request, $id)
{
    Product::findOrFail($id);

    $cart = session()->get('cart');

    if (isset($cart[$id])) {
        unset($cart[$id]);

        session()->put('cart', $cart);
    }

    return view('winkelmand');
}
matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
  • Well, i want to request the session array and then delete the specific product of which button is pressed. And i might need to specify by id to get that to work. I'm using $request->session()->forget('cart'); to remove it from the session, but this deletes the entire array. So i need a little help here because i'm not able to request the session array and delete ONE specific product whenever i press the 'delete' button – Rick Mondria Aug 31 '21 at 11:46
  • If you want to do that, you should get the `cart` from the session, directly remove the `id` from the `$cart`, and then store the `$cart` again in the session replacing the old one. – matiaslauriti Aug 31 '21 at 21:47
  • So you're saying that i should remove id from the variable $cart and then like "refresh" the session. Is there any sort of code that lets me do that? – Rick Mondria Sep 01 '21 at 09:31
  • @RickMondria your code is correct, except the part I changed in my answer, you change it how I did, and it should work as intended ! (Remember to delete `$id = $request->id`). See my answer (I edited it). – matiaslauriti Sep 01 '21 at 22:23
  • Thanks for answering! I changed it too what you commented and now i'm getting this error: Too few arguments to function App\Http\Controllers\CartController::store(), 1 passed in D:\PhpstormProjects\my-webshop-1\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 2 expected. the public function now has a blank $request and it says it's not being used – Rick Mondria Sep 02 '21 at 11:01
  • @RickMondria Oh, so you are not using the same URL as `delete` right, but with `delete` instead of `post`. Can you share your routes please ? – matiaslauriti Sep 02 '21 at 18:02
  • `Route::resource('/winkelmand', CartController::class);` is the route i use. My CartController is a resourcecontroller, which made the functions for me. Other routes i use are: `Route::resource('/producten', ProductController::class);` and `Route::get('/pay', [PaymentController::class, 'preparePayment']);` – Rick Mondria Sep 03 '21 at 08:35
  • Wait, so, the `HTML` (`Blade`) you shared is pointing to the `destroy` method. I helped you with the `store` method. What help do you need with the `destroy` method ? – matiaslauriti Sep 03 '21 at 22:03
  • Well i'm directing you to the `destroy` function because i need help with the button that makes sure that i delet one product from a Laravel session file. I included the whole controller, not one function (which you probably thought was `store`. I'm using the ``()forget method that removes a key from the session file, but i've only set it to 'cart' just to check if that method works. Now i'm trying to find a solution to delete one product from that session file so that's why i need some help. My teacher said that i should request that session and then pick out the specific product. – Rick Mondria Sep 04 '21 at 23:10
  • @RickMondria my bad about that, see my updated answer. If you still only have `cart` as a session id and then you have to find the `id` inside `cart`, my code will do it for you. Please, tell me if you are looking for that, else what else can I add or what am I missing ? – matiaslauriti Sep 05 '21 at 01:33
  • 1
    This was exactly what i was looking for. It's working as intended. Thank you so much for helping me out! – Rick Mondria Sep 05 '21 at 10:37