0

I just started learning Livewire and I am making a page to purchase books and add them to cart.

I made two Livewire components, one for the books and one for the cart. When I click purchase book everything works perfect and it was automatically added to the cart, but the problem is the cart doesn't update automatically and I need to reload the page to see the added books.

The books component:

class Book extends Component
{

    public $book,$price;

    protected $listeners = ['purchase' => 'incrementPrice'];

    public function render()
    {
        return view('livewire.book', [
            'books'=> Books::orderBy('id','asc')->get(),
            'purchases'=> Books::where('purchased',1)->paginate(20)
        ]);


    }

    public function purchase($id)
    {
        $book = Books::find($id);

        $book->purchased = 1;
        $book->save();

        if($book->save())
        {
            $this->dispatchBrowserEvent('bookPurchased');
        }
    }

    public function cancel($id)
    {
        $book = Books::find($id);

        $book->purchased = 0;
        $book->save();

        
    }


    public function OpenModal()
    {
        
        $this->emit('OpenModal');
    }


    public function incrementPrice()
    {
        $this->total = $price;
    }
    }

The book Livewire component:

      <div>
    
    <button wire:click="OpenModal()" type="button" class="btn btn-dark">
      @if( $purchases->total() >= 1 )
         CART <span class="badge badge-light">( {{ $purchases->total() }} )</span>
        @else
        CART
        @endif
    </button>
    
    <div class="row">
    @foreach( $books as $book )
        
    <div class="col-3">
    <div class="card" style="width: 18rem;">
        <div class="card-body">
        <h5 class="card-title" wire:model="book">{{ $book->book }}</h5>
        <p class="card-text" wire:model="price"> ${{ $book->price }} </p>
             @if(  $book->purchased == 0  )
        <a wire:click="purchase({{ $book->id }})" class="btn btn-primary">Purchase</a>
             @else
        <a  class="btn btn-primary disabled">Purchase</a>
        <a wire:click="cancel({{ $book->id }})"  class="btn btn-warning ">cancel</a>
             @endif
        </div>
    </div>
    </div>
        
         @endforeach
        </div>
    
    
        @livewire('cart')
    </div>

This is my View:

     <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>books</title>
    
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
    
        @livewireStyles
    </head>
    <body>
    
    <br><br>
    <div class="conatiner m-5">
        @livewire('book')
    </div>
        
    
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    
    
    @livewireScripts
    
    <script>
    
        window.addEventListener('bookPurchased', function(){
            alert('book was purchased !');
        });
    
    
        livewire.on('OpenModal' , ()=>{
            $('.Cart').modal('show');
        });
    </script>
    </body>
    </html>

The cart component:

        <?php
    
    namespace App\Http\Livewire;
    
    use Livewire\Component;
    use App\Models\Books;
    
    class Cart extends Component
    {
        public function render()
        {
            return view('livewire.cart', [
                'purchases'=> Books::where('purchased',1)->get()
            ]);
        }
    }

And this is the Cart Livewire component I am using as a modal:

        <div>
    <div class="modal fade Cart" wire:ignore.self id="exampleModalLong" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLongTitle">CART</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
              @foreach( $purchases as $purchase )
                <div class="card">
                    
                    <div class="card-body">
                        <p>{{ $purchase->book }}</p>
                        <p wire:model="p_price">${{ $purchase->price }}</p>
                    </div>
                    <br>
                    
                </div>
                @endforeach
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          </div>
        </div>
      </div>
    </div>
    </div>

1 Answer 1

1

you can use events for achieve it. Once you save the book, emit an event to Cart component to refresh it.

//book component...
...
  $book->save();
  $this->emit('cartRefresh');
...

//cart component
protected $listeners = ['cartRefresh' => '$refresh']; //it's going to re-render the component
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.