LaravelFan's avatar

Updating prices in cart

Hi,

I'm getting the message: "Property [currency_icon] does not exist on this collection instance" for line 133 let totalAmount = "{{ $product->currency_icon }}" + data in the cart.blade.php.

This is the cart.blade.php


@extends('frontend.master')

@section('title', 'Warenkorb')

@section('content')

    <!-- ======= Page Heading ======= -->

    <div class="page-heading-warenkorb">
        <h2>Cart</h2>
    </div>

    <!-- ======= Warenkorb ======= -->

    <div class="warenkorb">
        <div class="basket-wrapper">
            @foreach (Cart::content() as $item)
                <div class="basket-product">
                    <span class="total-items">Product</span>
                    <div class="item">
                        <div class="product-image">
                            <img src="{{ asset($item->options->image) }}" class="product-frame" />
                            <div class="product-details">
                                <h1>{{ $item->name }}</h1>
                                <p>Product-No. - {{ $item->id }}</p>
                                <div class="price">€ {{ number_format($item->price, 2) }}</div>
                                <div class="quantity-title">Quantity</div>
                                <div class="item-counter">
                                    <a href="{{ route('qty-decrement', $item->rowId) }}" class="minus"><span>-</span></a>
                                    <input type="text" value="{{ $item->qty }}" />
                                    <a href="{{ route('qty-decrement', $item->rowId) }}" class="plus"><span>+</span></a>
                                </div>
                                <a href="{{ route('remove-product', $item->rowId) }}" class="cart-button">Remove article</a>
                            </div>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>

        <!-- ======= Summary ======= -->

        <div class="summary">
            <div class="summary-total-items">
                <span class="total-items">Warenkorb-Summe</span>
            </div>
            <div class="summary-subtotal">
                <div class="subtotal-title">Zwischensumme</div>
                <div class="subtotal-value final-value" id="basket-subtotal">
                    € {{ $settings->currency_icon }}{getCartTotal()}
                </div>
                <div class="versand">Versand</div>
                <div class="subtotal-value final-value" id="basket-versand">
                    € 12.00
                </div>
                <div class="versand-land">Versand nach Österreich</div>

                <!-- ======= Promo Code ======= -->

                <div class="basket-module">
                    <label for="promo-code">Gutschein hinzufügen</label>
                    <input id="promo-code" type="text" name="promo-code" maxlength="5" class="promo-code-field" />
                    <button class="promo-code-cta">Übernehmen</button>
                </div>
            </div>
            <div class="summary-total">
                <div class="total-title">Gesamtsumme</div>
                <div class="tax">Einschließlich € 17,00 MwSt. 20 % AT</div>
                <div class="total-value final-value" id="basket-total">€ {{ $settings->currency_icon }}{getCartTotal()}
                </div>
            </div>
            <div class="summary-checkout">
                <button class="checkout-button">Weiter zur Kasse</button>
            </div>
        </div>
    </div>

    <!-- ======= Banner No. 5 ======= -->

    <div class="highlights-container-two">
        <div class="highlights">
            <div class="card-three">
                <img class="klebestreifen-two" />
                <img src="/frontend/assets/images/media_64586f31673d1.JPG" />
            </div>
            <div class="card-one">
                <blockquote>
                    <h2>Sommermode für sie</h2>
                    <img src="frontend/assets/images/Wellegrünkurz.svg" />
                    <p>
                        Lorem ipsum dolor sit amet consectetur adipisicing elit.
                        Laudantium dicta reiciendis dolores molestiae? Quis expedita rem
                        odit similique rerum, velit consequuntur consectetur atque optio,
                        numquam corrupti repellendus deserunt natus! Quo? Lorem ipsum
                        dolor sit amet consectetur, adipisicing elit. Consequuntur labore
                        rem, consequatur repudiandae esse consectetur. Voluptatem rem,
                        placeat commodi ipsum deserunt nam laudantium hic eius nulla.
                        Expedita itaque odio quisquam.
                    </p>
                </blockquote>
            </div>
        </div>
    </div>

@endsection

@push('scripts')
    <script>
        $(document).ready(function() {
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            // Incriment product quantity
            $('.qty-increment').on('click', function() {
                let input = $(this).siblings('.product-qty');
                let quantity = parseInt(input.val()) + 1;
                let rowId = input.data('rowid');
                input.val(quantity);

                $.ajax({
                    url: "{{ route('cart.sidebar-product-total') }}",
                    method: 'POST',
                    data: {
                        rowId: rowId,
                        quantity: quantity
                    },
                    success: function(data) {
                        if (data.status === 'success') {
                            let productId = '#' + rowId;
                            let totalAmount = "{{ $product->currency_icon }}" + data
                                .product_total
                            $(productId).text(totalAmount)

                            renderCartSubTotal()
                            calculateCouponDescount()

                            toastr.success(data.message)
                        } else if (data.status === 'error') {
                            toastr.error(data.message)
                        }
                    },
                    error: function(data) {

                    }
                })
            })

            // Decrement product quantity
            $('.qty-decrement').on('click', function() {
                let input = $(this).siblings('.product-qty');
                let quantity = parseInt(input.val()) - 1;
                let rowId = input.data('rowid');

                if (quantity < 1) {
                    quantity = 1;
                }

                input.val(quantity);

                $.ajax({
                    url: "{{ route('cart.sidebar-product-total') }}",
                    method: 'POST',
                    data: {
                        rowId: rowId,
                        quantity: quantity
                    },
                    success: function(data) {
                        if (data.status === 'success') {
                            let productId = '#' + rowId;
                            let totalAmount = "{{ $product->currency_icon }}" + data
                                .product_total
                            $(productId).text(totalAmount)

                            renderCartSubTotal()
                            calculateCouponDescount()

                            toastr.success(data.message)
                        } else if (data.status === 'error') {
                            toastr.error(data.message)
                        }
                    },
                    error: function(data) {

                    }
                })

            })

    @push('scripts')
    <script>
        $(document).ready(function() {
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            // Incriment product quantity
            $('.qty-increment').on('click', function() {
                let input = $(this).siblings('.product-qty');
                let quantity = parseInt(input.val()) + 1;
                let rowId = input.data('rowid');
                input.val(quantity);

                $.ajax({
                    url: "{{ route('cart.sidebar-product-total') }}",
                    method: 'POST',
                    data: {
                        rowId: rowId,
                        quantity: quantity
                    },
                    success: function(data) {
                        if (data.status === 'success') {
                            let productId = '#' + rowId;
                            let totalAmount = "{{ $product->currency_icon }}" + data
                                .product_total
                            $(productId).text(totalAmount)

                            renderCartSubTotal()
                            calculateCouponDescount()

                            toastr.success(data.message)
                        } else if (data.status === 'error') {
                            toastr.error(data.message)
                        }
                    },
                    error: function(data) {

                    }
                })
            })

            // Decrement product quantity
            $('.qty-decrement').on('click', function() {
                let input = $(this).siblings('.product-qty');
                let quantity = parseInt(input.val()) - 1;
                let rowId = input.data('rowid');

                if (quantity < 1) {
                    quantity = 1;
                }

                input.val(quantity);

                $.ajax({
                    url: "{{ route('cart.sidebar-product-total') }}",
                    method: 'POST',
                    data: {
                        rowId: rowId,
                        quantity: quantity
                    },
                    success: function(data) {
                        if (data.status === 'success') {
                            let productId = '#' + rowId;
                            let totalAmount = "{{ $product->currency_icon }}" + data
                                .product_total
                            $(productId).text(totalAmount)

                            renderCartSubTotal()
                            calculateCouponDescount()

                            toastr.success(data.message)
                        } else if (data.status === 'error') {
                            toastr.error(data.message)
                        }
                    },
                    error: function(data) {

                    }
                })

            })       
            

        })
    </script>
@endpush


This is the CartController


<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;
use Gloudemans\Shoppingcart\Facades\Cart;

class CartController extends Controller
{
    public function cart()
    {
        $product = Product::all();
        return view('frontend.cart', compact('product'));
    }

    // This is for updating the product in the cart
    public function updateProductQty(Request $request)
    {
        Cart::update($request->rowId, $request->quantity);
        $productTotal = $this->getProductTotal($request->rowId);
        return response(['status' => 'success', 'message' => 'Product Quantity Updated!', 'product_total' =>$productTotal]);
    }

    // Get the product total amount
    public function getProductTotal($rowId)
    {
        $product= Cart::get($rowId);
        $total = ($product->price + $product->options->variants_total) * $product->qty;
        return $total;
    }

    // This is for adding a product to the cart
    public function addToCart($productId)
    {
        $product = Product::findOrFail($productId);

        Cart::add([
            'id' => $product->id,
            'name' => $product->product_name,
            'qty' => 1,
            'price' => $product->price,
            'weight' => 0,
            'options' => [
                'image' => $product->product_image
            ]
        ]);
        return redirect()->back()->with('success', 'Produkt liegt in den Warenkorb!');
    }


    // This is for incrementing a product in the cart
    public function qtyIncrement($id)
    {
        $product = Cart::get($id);
        $updateQty = $product->qty + 1;

        Cart::update($id, $updateQty);

        return redirect()->back()->with('success', 'Product incremented successful!');
    }

    // This is for decrementing a product in the cart
    public function qtyDecrement($id)
    {
        $product = Cart::get($id);
        $updateQty = $product->qty - 1;
        if ($updateQty > 0) {
            Cart::update($id, $updateQty);
        }

        return redirect()->back()->with('success', 'Product decremented successfully!');
    }

    // This is for removing a product from the cart
    public function removeProduct($id)
    {
        Cart::remove($id);

        return redirect()->back();
    }
}


web.php:


Route::get('cart', [CartController::class, 'cart'])->name('cart');
Route::get('add-to-cart/{product_id}', [CartController::class, 'addToCart'])->name('add-to-cart');
Route::get('qty-increment/{rowId}', [CartController::class, 'qtyIncrement'])->name('qty-increment');
Route::get('qty-decrement/{rowId}', [CartController::class, 'qtyDecrement'])->name('qty-decrement');
Route::get('remove-product/{rowId}', [CartController::class, 'removeProduct'])->name('remove-product');
Route::post('cart/update-quantity', [CartController::class, 'updateProductQty'])->name('cart.update-quantity');


Finally, I have the scripts.blade.php:


<script>
    $(document).ready(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        // add product into cart
        $(document).on('submit', '.shopping-cart-form', function(e) {
            e.preventDefault();
            let formData = $(this).serialize();

            $.ajax({
                method: 'POST',
                data: formData,
                url: "{{ route('add-to-cart') }}",
                success: function(data) {
                    if(data.status === 'success'){
                        getCartCount()
                        fetchSidebarCartProducts()
                        $('.mini_cart_actions').removeClass('d-none');
                        toastr.success(data.message);
                    }else if (data.status === 'error'){
                        toastr.error(data.message);
                    }
                },
                error: function(data) {

                }
            })
        })

        function getCartCount() {
            $.ajax({
                method: 'GET',
                url: "{{ route('cart-count') }}",
                success: function(data) {
                    $('#cart-count').text(data);
                },
                error: function(data) {

                }
            })
        }

        function fetchSidebarCartProducts() {
            $.ajax({
                method: 'GET',
                url: "{{ route('cart-products') }}",
                success: function(data) {
                    console.log(data);
                    $('.mini_cart_wrapper').html("");
                    var html = '';
                    for (let item in data) {
                        let product = data[item];
                        html += `
                        <li id="mini_cart_${product.rowId}">
                            <div class="wsus__cart_img">
                                <a href="{{ url('product-detail') }}/${product.options.slug}"><img src="{{ asset('/') }}${product.options.image}" alt="product" class="img-fluid w-100"></a>
                                <a class="wsis__del_icon remove_sidebar_product" data-id="${product.rowId}" href=""><i class="fas fa-minus-circle"></i></a>
                            </div>
                            <div class="wsus__cart_text">
                                <a class="wsus__cart_title" href="{{ url('product-detail') }}/${product.options.slug}">${product.name}</a>
                                <p>{{ $settings->currency_icon }}${product.price}</p>
                                <small>Variants total: {{ $settings->currency_icon }}${product.options.variants_total}</small>
                                <br>
                                <small>Qty: ${product.qty}</small>
                            </div>
                        </li>`
                    }

                    $('.mini_cart_wrapper').html(html);

                    getSidebarCartSubtoal();

                },
                error: function(data) {

                }
            })
        }

        // reomove product from sidebar cart
        $('body').on('click', '.remove_sidebar_product', function(e) {
            e.preventDefault()
            let rowId = $(this).data('id');
            $.ajax({
                method: 'POST',
                url: "{{ route('cart.remove-sidebar-product') }}",
                data: {
                    rowId: rowId
                },
                success: function(data) {
                    let productId = '#mini_cart_' + rowId;
                    $(productId).remove()

                    getSidebarCartSubtoal()

                    if ($('.mini_cart_wrapper').find('li').length === 0) {
                        $('.mini_cart_actions').addClass('d-none');
                        $('.mini_cart_wrapper').html(
                            '<li class="text-center">Cart Is Empty!</li>');
                    }
                    toastr.success(data.message)
                },
                error: function(data) {
                    console.log(data);
                }
            })
        })

        // get sidebar cart sub total
        function getSidebarCartSubtoal() {
            $.ajax({
                method: 'GET',
                url: "{{ route('cart.sidebar-product-total') }}",
                success: function(data) {
                    $('#mini_cart_subtotal').text("{{ $settings->currency_icon }}" + data);
                },
                error: function(data) {

                }
            })
        }

        // add product to wishlist
        $('.add_to_wishlist').on('click', function(e){
            e.preventDefault();
            let id = $(this).data('id');

            $.ajax({
                method: 'GET',
                url: "{{route('wishlist.store')}}",
                data: {id:id},
                success:function(data){
                    if(data.status === 'success'){
                        $('#wishlist_count').text(data.count)
                        toastr.success(data.message);
                    }else if(data.status === 'error'){
                        toastr.error(data.message);
                    }
                },
                error: function(data){
                    console.log(data);
                }
            })
        })

        // newsletter
        $('#newsletter').on('submit', function(e){
            e.preventDefault();
            let data = $(this).serialize();

            $.ajax({
                method: 'POST',
                url: "{{route('newsletter-request')}}",
                data: data,
                beforeSend: function(){
                    $('.subscribe_btn').text('Loading...');
                },
                success: function(data){
                    if(data.status === 'success'){
                        $('.subscribe_btn').text('Subscribe');
                        $('.newsletter_email').val('');
                        toastr.success(data.message);

                    }else if(data.status === 'error'){

                        $('.subscribe_btn').text('Subscribe');
                        toastr.error(data.message);
                    }
                },
                error: function(data){
                    let errors = data.responseJSON.errors;
                    if(errors){
                        $.each(errors, function(key, value){
                            toastr.error(value);
                        })
                    }
                    $('.subscribe_btn').text('Subscribe');
                }
            })
        })


        $('.show_product_modal').on('click', function(){
            let id = $(this).data('id');

            $.ajax({
                mehtod: 'GET',
                url: '{{ route("show-product-modal", ":id" ) }}'.replace(":id", id),
                beforeSend: function(){
                    $('.product-modal-content').html('<span class="loader"></span>')
                },
                success: function(response){
                    $('.product-modal-content').html(response)
                },
                error: function(xhr, status, error){

                },
                complete: function(){

                }
            })
        })

    })
</script>


Grateful for your guidance

0 likes
2 replies
Amaury's avatar

@mamunsson At first glance there is a problem in the CartController:

public function cart()
    {
        $product = Product::all();
        return view('frontend.cart', compact('product'));
    }

$product variable in your view is a Collection… You cannot access $product->currency_icon in your view.

Then, your design and the code seems too confusing to me. It would be better to stick to the index, create, store, update, delete… methods in your controllers. It’s a good practice, because it forces you to better design your application.

Maybe the Laracats series 'Build a Web Shop From A-Z' would be very beneficial to you: https://laracasts.com/series/build-a-web-shop-from-a-z

1 like

Please or to participate in this conversation.