October 26, 2024
Chicago 12, Melborne City, USA
PHP

How to properly configure Livewire in a project? (after unsuccessfully trying to do it)


A few words about the site:

A website made with Laravel 11 is an online e-cigarette store. After I configured the general functionality of the site and the cart, there was a need to make the page not reload every time I click on the cart button, or remove an item from the cart.

The code part (don’t judge too harshly, I wanna to improve myself)

  1. Method index() that works with index.blade.php
    ProductsController:
public function index()
    {
        $cigarettes = Cigarette::all();
        $liquids = Liquid::all();
        $cart = Cart::content();
        $total = Cart::priceTotal(); 

        return view('index', compact('cigarettes', 'liquids','cart', 'total'));
    }

2.A part of the code that is responsible for displaying goods (cigarettes and liquids)

index.blade.php:

<div class="grid">
                    {{-- Cigarettes --}}
                    @forelse($cigarettes as $cigarette)
                        <x-cigarette-card :cigarette="$cigarette"
                                          :cart="$cart"
                        />
                    @empty
                        <div class="#">
                            No cigarettes in the database
                        </div>
                    @endforelse

                    {{-- Liquids --}}
                    @forelse($liquids as $liquid)
                        <x-liquid-card :liquid="$liquid"
                                       :cart="$cart"
                        />

                    @empty
                        <div class="#">
                            No liquids in the database
                        </div>
                    @endforelse
                </div>

(i know that include $cart variable into component with code for product isn’t really fancy, but its my first big project)

3.Code of my components:
components/cigarette-card.blade.php:
@props([‘cigarette’, ‘cart’])

<div class="grid__item">
    <article class="product {{ $cigarette->type }}">
        {{-- Image --}}
        <img class="product__image" src="{{ asset('./storage/' . $cigarette->image) }}" alt="{{ $cigarette->name }}" />

        <div class="product__description">
            {{-- Name --}}
            <h2 class="product__name">{{ $cigarette->name }}</h2>
            {{-- Info --}}
            <div class="product__info">
                ✔&nbsp;Moc - {{ $cigarette->strength }}%
                <br>
                ✔&nbsp;{{ $cigarette->puffs }} zaciągnięć
                <br>
                ✔&nbsp;Smak: {{ $cigarette->flavor }}
            </div>
            {{-- Price --}}
            <p class="product__price">Cena: {{ $cigarette->price }} zł</p>
        </div>

{{-- Buttons for guests: [Buy] [Delete from cart] [Add to cart] --}}
@guest...@endguest

{{-- Buttons for admins: Admin Panel: [Delete product] [Edit page button] [Show page button] --}}
@auth...@endauth
</article>
</div>

<div>
    {{ $slot }}
</div>

And I’d like to show a form for adding product in cart:
(THIS CODE IS SIMILAR FOR liquids)

components/cigarette-card.blade.php

                {{-- Cart button --}}
                <form action="{{ route('cart.store') }}" method="POST">
                    @csrf

                    {{-- Quantity control --}}
                    <div class="quantity-control">
                        <button type="button" class="quantity-button decrease">-</button>

                        <input type="number" name="quantity" class="quantity-input" 
                        value="1" min="1" readonly/>

                        <button type="button" class="quantity-button increase">+</button>
                    </div>

                    {{-- Product id --}}
                    <input type="hidden" name="product_id" value="{{ $cigarette->id }}">
                    <input type="hidden" name="type" value="cigarette">

                    {{-- Cart button submit (with an image) --}}
                    <button type="submit" 
                     class="button product__button" aria-label="Dodaj do koszyka">

                        <svg class="button__icon" width="20" height="20">
                            <use href="./storage/images/footer-icons/symbol-defs.svg#icon-shopping-cart"></use>
                        </svg>
                    </button>
                </form>

Also I wanna to show a delete from cart form:

                {{-- Delete from cart --}}
                <form action="{{ route('cart.delete') }}" method="POST">
                    @csrf
                    <!-- rowId -->
                    <input type="hidden" name="rowId" value="{{ $cart->where('id', $cigarette->id)->first()->rowId }}">
                    <!-- Product id -->
                    <input type="hidden" name="product_id" value="{{ $cigarette->id }}">
                    <!-- Type -->
                    <input type="hidden" name="type" value="cigarette">

                    <!-- Delete from cart button -->
                    <button type="submit" class="#">Delete from cart</button>
                </form>

Those parts of code (forms are similar for liquids)

What did I try:

First try: After installing Livewire I created two separate components for cigarettes and liquids, then after moving their code to the livewire component I made another livewire component that stored the code for the product (so the cigarette-card and liquid-card code was now in the livewire component, in other words I had a component within a component). After I edited the code in the methods of these components I was still getting page reloads

Second try: After that I decided to do things a bit differently, I made one livewire component, in which I put the code:

<div class="grid">
                    {{-- Cigarettes --}}
                    @forelse($cigarettes as $cigarette)
                        <x-cigarette-card :cigarette="$cigarette"
                                          :cart="$cart"
                        />
                    @empty
                        <div class="#">
                            No cigarettes in the database
                        </div>
                    @endforelse

                    {{-- Liquids --}}
                    @forelse($liquids as $liquid)
                        <x-liquid-card :liquid="$liquid"
                                       :cart="$cart"
                        />

                    @empty
                        <div class="#">
                            No liquids in the database
                        </div>
                    @endforelse
                </div> 

in this component I stopped using the code of cigarette-card and liquid-card components, i.e. now the code that used to be in the components appeared in the livewire component (this added difficulties, because the code became many times more). After reusing the livewire component's livewire method, I was still getting page reloads. 

My opinion:
My theory of what the problem is: maybe the problem lies in the fact that my project uses js code to open and close the cart page, which is a modal window.

Can anyone tell me how can I use Livewire in my project? 



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video