Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All LaravelShoppingcart methods don't work when using api call in laravel #367

Open
ahmedfaical opened this issue Jul 31, 2017 · 23 comments

Comments

@ahmedfaical
Copy link

ahmedfaical commented Jul 31, 2017

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?

@ahmedfaical ahmedfaical changed the title All LaravelShoppingcart don't work when using api call in laravel All LaravelShoppingcart methods don't work when using api call in laravel Jul 31, 2017
@Crinsane
Copy link
Owner

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.

@ahmedfaical
Copy link
Author

ahmedfaical commented Jul 31, 2017

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

@ahmedfaical
Copy link
Author

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

@matejsvajger
Copy link

@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.

@ahmedfaical
Copy link
Author

@matejsvajger I still get the same problem

@Crinsane
Copy link
Owner

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

@ahmedfaical
Copy link
Author

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);

@Crinsane
Copy link
Owner

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

@ahmedfaical
Copy link
Author

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

@ahmedfaical
Copy link
Author

ahmedfaical commented Jul 31, 2017

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 ?

@matejsvajger
Copy link

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

@ahmedfaical
Copy link
Author

ahmedfaical commented Jul 31, 2017

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)
	}
});

@ahmedfaical
Copy link
Author

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

@hakobfromlightin
Copy link

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

@jakus1
Copy link

jakus1 commented Sep 8, 2017

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.

@codeitlikemiley
Copy link

codeitlikemiley commented Oct 13, 2017

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

@jsdecena
Copy link

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 )

@OctaneInteractive
Copy link

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?

@jordantsap
Copy link

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

@jamalali
Copy link

Is this still an isue for anyone else?

@stanislavkhatko
Copy link

stanislavkhatko commented Sep 6, 2018

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.

@chrisvidal
Copy link

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

@kratos619
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests