Laravelshoppingcart: All LaravelShoppingcart methods don't work when using api call in laravel

Created on 31 Jul 2017  路  23Comments  路  Source: Crinsane/LaravelShoppingcart

Hello i have i problem and i can't resolve it All LaravelShoppingcart methods don't work when using api call in laravel to retrieve session data? Any idea?

Most helpful comment

I had this problem just now and this is how I fixed it. First you need to change the api middleware group to:

'api' => [
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    'throttle:60,1',
    'bindings',
],

in

app/Http/Kernel.php

It is important that all entries are there and that they are in this order.

All 23 comments

I need more information to debug this. Are the API calls using a session or not? What is the code you use, which version of Laravel and this package. How can I reproduce this problem. Otherwise I can't help you.

I'm using Redis driver with laravel 5.4

This is the code in my routes/api.php : 
Route::get('/test', "Frontoffice\CartController@test");

I access to my api in browser like this : www.example.com/api/test
So when i'm using this function :

    public function test(){
        Cart::add(18, 'nameee', 2, 44, array('size' => 'De4', 'stock' => '2'));
        return Cart::content();
    }

I get content but when i delete the line Cart::add :

    public function test(){
        return Cart::content();
    }

I can't get old session data, i get nothing

Any idea please that can help me? it's like that a new session created or something like that, Can you help me?

@leonfather Laravel routes in routes/api.php don't have a session by default. Either move your route to routes/web.php -> Route::get('/api/test', "Frontoffice\CartController@test"); or enable sessions via middleware in API route group.

@matejsvajger I still get the same problem

Does the normal laravel session work? Can you put something in the session and retreive it?

yes it works i'm using redis in session I store my session data using
Redis::set('test', $value);
And i retrieve this value
Redis::get('test', $value);

That's not the Laravel session you're using. You're using Redis directly, and not via the session manager (which this package is using) Try with the Session facade please

https://laravel.com/docs/5.4/session

i'm using session facade i only change SESSION_DRIVER=redis from file to redis

But when i'm doing test to see if laravel session work or now i get those results :

public function test(Request $request){
    $request->session()->put('key', 'value');
    $key = $request->session()->get('key');
    return response($key);
}

in the same route /test i get result : value
But when trying to access this value from an other route i get 'value'. Any idea from where i get the problem ?

@leonfather you're setting and retrieving the session value in the same call. Try retrieving it in a different function.

yes i'm doing tests now and laravel session works fine, Any idea from where i get the problem ?
This is my code :
CartController.php

<?php

namespace App\Http\Controllers\Frontoffice;

use Gloudemans\Shoppingcart\Facades\Cart;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class CartController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index($prefix)
    {

        //Cart::destroy();
        //dd(Config::get(tldConfig().'.curr_symbol'));

        //$this->updateCartStock();

        //Cart::add(18, 'name one', 2, 44, array('size' => 'De4', 'stock' => '2'));


        if($prefix == translate('global.cart')){
            return view('frontoffice.cart.index');
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */

    public function create()
    {

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

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

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }

    public function addToCart(Request $request){
        $item = $request->input('item');
        $stock = $item['stock'] - $item['qty'];
        Cart::add($item['ref'], $item['name'], $item['qty'], $item['price'], array('size' => $item['size'], 'stock' => $stock));

        return response(Cart::content());
    }

    public function cartContent(){
        $cartContent = Cart::content();
        return response($cartContent);
    }

    public function removeFromCart(Request $request){
        $rowId = $request->input('rowId');
        Cart::remove($rowId);
    }

    public function updateCart(Request $request){
        $rowId = $request->input('rowId');
        $data = $request->input('data');
        Cart::update($rowId, $data[0]);
        $subtotal = Cart::subtotal(0);
        $countItem = Cart::count();
        return response(array('subTotal' => $subtotal, 'countItem' => $countItem));
    }

    public function cartSubTotal(){
        $subTotal = Cart::subtotal(0);
        return response($subTotal);
    }

    public function countItem(){
        $countItem = Cart::count();
        return response(array('countItem' => $countItem));
    }

    public function updateCartStock(){

        $cart = Cart::content();
        $refs = array();
        foreach($cart as $key => $value){
            $refs[] = $value->id;
        }

        $stocks = DB::table('products_references_has_stocks AS prhs')
            ->whereIn('prhs.prod_ref_id', $refs)->select('prhs.prod_ref_id', DB::raw("SUM(`prhs`.`stock`) AS stock"))
            ->groupBy('prhs.prod_ref_id')->get();

        $getStock = array();
        foreach($stocks->toArray() as $key => $value){
            $getStock[$value->prod_ref_id] = $value->stock;
        }

        foreach($cart as $key => $value){
            Cart::update($key, ['options'  => ['stock' => $getStock[$value->id] - $value->qty, 'size' => $value->options->size]]);
        }
    }


    public function test1(Request $request){
        //Cart::add(18, 'name one', 2, 44, array('size' => 'De4', 'stock' => '2'));
        //Cart::add(19, 'name two', 5, 55, array('size' => 'De4', 'stock' => '2'));

        $request->session()->put('key', 'value');

        $key = $request->session()->get('key');
        $response = Cart::content();
        return response($key);
    }


    public function test2(Request $request){
        //Cart::add(18, 'name one', 2, 44, array('size' => 'De4', 'stock' => '2'));
        //Cart::add(19, 'name two', 5, 55, array('size' => 'De4', 'stock' => '2'));


        $key = $request->session()->get('key');
        return response($key);
    }
}

cart/index.blade.php (cart file)

@section('content')
                    <table v-if="Object.keys(cartItems).length > 0" border="1">

                        <thead>
                            <tr>
                                <th width="5%">Photo </th>
                                <th width="50%">Name</th>
                                <th width="15%">Prix unitaire</th>
                                <th width="15%">Qty</th>
                                <th width="15%">Prix</th>
                            </tr>
                        </thead>

                        <tbody>

                        <tr v-for="item in cartItems">
                            <td>
                                <a @click="removeFromCart(item.rowId)">Delete</a>
                            </td>
                            <td> @{{ item.name }} - @{{ item.options.size?item.options.size : '' }} ----- Current Stock : @{{ item.options.stock }}</td>
                            <td>
                                @{{ item.price }} {{ Config::get(tldConfig().'.curr_symbol') }}
                            </td>
                            <td>
                                <v-btn @click.native="qtyLess(item)" fab dark small primary> - </v-btn>
                                <input width="2" v-model="item.qty" v-on:change="updateCart(item.rowId, [{'qty':item.qty}])"/>
                                <v-btn @click.native="qtyMore(item)" fab dark small primary> + </v-btn>
                            </td>
                            <td><transition name="fade-transition">
                                    <p v-if="!loading">@{{ item.price * item.qty }} {{ Config::get(tldConfig().'.curr_symbol') }} </p>
                                </transition>
                            </td>
                        </tr>


                        <tr>
                            <td></td>
                            <td></td>
                            <td>Sous total</td>
                            <td><transition name="fade-transition">
                                    <p v-if="!loading">@{{ subTotal }} {{ Config::get(tldConfig().'.curr_symbol') }}</p>
                                </transition>
                            </td>
                        </tr>

                        </tbody>
                    </table>

                    <p v-if="Object.keys(cartItems).length == 0">Votre panier ne contient aucun article</p>

                @endsection

vue js file :

require('./bootstrap');

import Vue from 'vue';

// Validation
import VeeValidate from "vee-validate";
import VeeValidateMessagesBR from "vee-validate/dist/locale/fr";
VeeValidate.Validator.addLocale(VeeValidateMessagesBR);
Vue.use(VeeValidate, {locale: 'fr', errorBagName: 'vErrors'})

import Vuetify from 'vuetify'
Vue.use(Vuetify)

Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name=_token]').getAttribute('content');

import headerMixin from './headerMixin'
import footerMixin from './footerMixin'

new Vue({
    el: "#app",
    mixins: [footerMixin, headerMixin],
    data () {
        return {
            subTotal : 0,
            loading : false,
            qty : 1,
            dialog : false,
            dialogContent : '',
            addToCartLoading : true,
                        countItem : 0,
            dialogWidth : '',
            cartItems :[]
        }
    },
    methods: {
        qtyMore(item){
            if(item.qty < item.options.stock){
                item.qty = item.qty + 1
                this.updateCart(item.rowId, [{'qty':item.qty}])
            }
        },
        qtyLess(item){
            if(item.qty > 1){
                item.qty = item.qty - 1
                this.updateCart(item.rowId, [{'qty':item.qty}])
            }
        },
        updateCart(rowId, data){
            this.loading = true
            this.$http.put('/api/updateCart', {rowId : rowId, data : data}).then(response => {
                this.loading = false
                this.subTotal = response.data.subTotal
                this.countItems()
            });
        },
        checkQty(item){
            if(item.qty <= 0){
                alert('Valeur minimal est 1')
                item.qty = 1
            }
            if(item.qty > Number(item.options.stock)){
                alert('D茅sol茅, il n en reste que '+item.options.stock+' en stock')
                item.qty = item.options.stock
            }
        },
        removeFromCart(rowId){
            this.loading = true
            this.$http.post('/api/remove', {rowId : rowId}).then(response => {
                Vue.delete(this.cartItems, rowId);
                this.cartSubTotal()
                this.countItems()
                this.loading = false
            });
        },
               cartSubTotal(){
            this.loading = true
            this.$http.get('/api/cartSubTotal').then(response => {
                this.loading = false
                this.subTotal = response.data
            });
        },
        countItems(){
            this.loading = true
            this.$http.get('/api/countItem').then(response => {
                this.loading = false
                this.countItem = response.data.countItem
            });
        },
        cartContent() {
            this.$http.get('/api/cartContent').then(response => {
                this.cartItems = response.data
                this.cartSubTotal()
            });
        }
    },
        mounted: function () {
        this.countItems()
        this.cartContent()
        console.log(this.countItem)
    }
});

in CartController in index method :

public function index($prefix)
    {
        Cart::add(18, 'name one', 2, 44, array('size' => 'De4', 'stock' => '2'));
        if($prefix == translate('global.cart')){
            return view('frontoffice.cart.index');
        }
    }

With this code i get content in cart but if i comment Cart::add(18,...... i get nothing in cart content

I have the same problem with cart, any help will be appreciated

I had this problem just now and this is how I fixed it. First you need to change the api middleware group to:

'api' => [
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    'throttle:60,1',
    'bindings',
],

in

app/Http/Kernel.php

It is important that all entries are there and that they are in this order.

well 3 things you need to observe since im using this basically for vue SPA, and using api calls...
your api endpoints should be located in your routes/web.php
secondly, you need to make session lifetime, that way, even if the user abandon it, laravel will still recognize the session , so all data about the cart will be still there...
third , you need to use
localstorage that will read the stored cart object , im using a modular store VUEX.
by default the localstorage check for the cart object if stored if not check my global state initial state
which also has the Cart Object. Lastly if it cannot find the cart , then it just an empty array

The API is session-less since it is token-based. Surely, you will not be able to retrieve the items added in the current session since the token might not know who is the currently logged user ( unless you make the app known based on token and logged it in )

Hi @codeitlikemiley, I'm creating a Vue SPA.

I've switched to the web routes, but Cart::content() still isn't giving me anything.

Are you using sessions?

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Product;
use Gloudemans\Shoppingcart\Facades\Cart;
use Session;

Is this still an isue for anyone else?

It's still an issue for me. When I add those middlewares to 'api' group, it brakes Passport auth:api system.

The workaround solution is to move shopping cart routes to web.php, wherein 'web' middleware session already exists and retrieves cart correctly.

I found a solution by inserting the 'web' middleware in the api routes.php

Route::group([
        'middleware' => ['web'],
        'prefix' => 'api',
        'namespace' => 'Api\Http\Controllers'
    ], function () {

hope that helps

api_add
this is add function to add item into cart
api_function
this is cart content function
api_route
this is route api to call that function

but in response i dont get any data in android device please helpppppppppppppppp

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ellgibug picture ellgibug  路  5Comments

yansentan picture yansentan  路  6Comments

morganchorlton3 picture morganchorlton3  路  3Comments

wasid picture wasid  路  8Comments

rubelkhan447 picture rubelkhan447  路  6Comments