@aung htet paing can you show 'Api\CartController@index' method?
i figured out that response from api is returning object
can you show the object?
Hello, i'm doing laravel e-commerce project for the first time. And faced a error when product in cart is remove from cart. Splice() doesn't work.
here is my web.php
Route::get('/cart', 'CartController@index')->name('cart.index');
Route::post('/cart/{product}', 'CartController@store')->name('cart.store');
Route::delete('/cart/{product}', 'CartController@destroy')->name('cart.delete');
Route::get('/products', 'ProductController@index')->name('products.index');
Route::get('/products/{product:slug}', 'ProductController@show')->name('products.show');
Route::get('api/cart', 'Api\CartController@index');
Route::get('api/cart/clear', 'Api\CartController@clear')->name('cart.clear');
and CartController.php
public function index()
{
return Inertia::render('cart');
}
public function store(Product $product, Cart $cart)
{
$cart->add($product);
}
public function destroy(Product $product, Cart $cart)
{
$cart->remove($product);
}
Cart.php
public function add($product)
{
$cart = session()->has($this->cartKey()) ? session($this->cartKey()): new Collection;
if(isset($cart[$product->id]))
{
$cart[$product->id]->quantity++;
session()->put($this->cartKey(), $cart);
// return response('successfully added to your cart');
}
else {
$cart[$product->id] = $product;
$cart[$product->id]->quantity++;
session()->put($this->cartKey(), $cart);
// return response('item is already in your cart. Quantity has been updated!');
}
}
public function remove($product)
{
session()->pull($this->cartKey() . ".{$product->id}");
}
protected function cartKey()
{
return "cart";
}
and then i call cart from api to vue cart.vue
<template>
<breeze-authenticated-layout>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<!-- <button @click="clearCart">Delete cart</button> -->
<div v-if="products">
<div v-for="(product, index) in products" :key="product.id">
<h2>
{{product.name}} - {{index}}
</h2>
<button @click="removeFromCart(index)">Delete</button>
</div>
</div>
<div v-else>
No Products in Session
</div>
</div>
</div>
</div>
</div>
</breeze-authenticated-layout>
</template>
<script>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated'
import axios from 'axios'
export default {
components: {
BreezeAuthenticatedLayout,
},
data() {
return {
products: []
}
},
mounted() {
this.fetch()
},
methods: {
fetch() {
axios.get('/api/cart')
.then(response => {
this.products = response.data
console.log(response.data);
})
},
removeFromCart(id){
// console.log(this.products);
this.products.splice(id, 1);
axios.delete(`/cart/${id}`);
}
}
}
</script>
<style lang="scss" scoped>
</style>
After some attempts, i figured out that response from api is returning object. If it return array, splice is working fine. But i don't know how to change, object to array that is from api.
I'm sorry if i made mistake in asking question. This is my question for the first time.
@aung htet paing javascript do not support array with numeric keys not in default order (staring from 0, one by one), so, it's used as object.
Do not use product id as array key (you have it in item and can use it for seraching)
Or you can do the following, for example
in Api\CartController
public function index()
{
return array_values(session("cart"));
}
in cart.vue
<div v-for="(product, index) in products" :key="product.id">
<h2>
{{product.name}} - {{product.id}}
</h2>
<button @click="removeFromCart(index)">Delete</button>
</div>
// ...
removeFromCart(index){
let _this = this;
let product = this.products[index]
// console.log(this.products);
this.products.splice(id, 1);
axios.delete(`/cart/${product.id}`)
.then(response => {
_this.products.splice(index, 1)
});
}
Please or to participate in this conversation.