Failed to add item to the cart using jquery and php

Hi Team

I have cart has an image with price, desc and quantity also there is a button to add to cart. The problem i think is on my client side and php side, because when debugging i get the same error "success: Failed invalid request(php side) and client side “Failed to add to cart”. How can i fix this issue? please advice me so can amend the changes to my code.

// html code

    <div class="col-lg-4 col-md-6 col-sm-12 pb-1">
    <div class="card product-item border-0 mb-4">
        <div class="card-header product-img position-relative overflow-hidden bg-transparent border p-0">
            <img class="img-fluid w-100" src="img/product-1.jpg" alt="">
        </div>
        <div class="card-body border-left border-right text-center p-0 pt-4 pb-3">
            <h6 class="text-truncate mb-3">Colorful Stylish Shirt 0</h6>
            <div class="d-flex justify-content-center">
                <h6>R120.00</h6><h6 class="text-muted ml-2"><del>R120.00</del></h6>
            </div>
        </div>
        <div class="card-footer d-flex justify-content-between bg-light border">
            <a href="#" class="btn btn-sm text-dark p-0 view-details-btn" id="cart-0"><i class="fas fa-eye text-primary mr-1"></i>View Detail</a>
            <a href="#" class="btn btn-sm text-dark p-0 add-to-cart-btn" id="cart-123">
            <i class="fas fa-shopping-cart text-primary mr-1"></i>Add To Cart</a>
        </div>
    </div>
</div>

// jquery code

$(document).ready(function() {
  $('.add-to-cart-btn').on('click', function(e) {
    e.preventDefault();

    var itemId = $(this).attr('id').split('-')[1];

    // Retrieve product information from the cart table based on the item ID
      var productInfo = {
      id: 123,
      name: "Product Name",
      price: 10.99,
      quantity: 1
  };


    // Send an AJAX request to update the cart in the database
    $.ajax({
      url: 'update-cart.php',
      method: 'POST',
      data: productInfo,
      success: function(response) {
        // Handle the response from the server
        if (response.success) {
          // Update the cart badge count
          var cartBadge = $('.fa-shopping-cart + .badge');
          var cartCount = parseInt(cartBadge.text());
          cartBadge.text(cartCount + 1);
        } else {
          // Handle the error scenario
          alert('Failed to add item to the cart. Please try again.');
        }
      },
      error: function() {
        alert('An error occurred while processing your request. Please try again later.');
      }
    });
  });
});

// php code

<?php

// Check if the AJAX parameter is present
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
    // Proceed with the AJAX request

    // Database connection details
    $host = 'localhost';
    $dbname = 'ecommerce_store';
    $username = 'root';
    $password = '';

    // Retrieve the product information from the AJAX request
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['id']) && isset($_POST['name']) && isset($_POST['price']) && isset($_POST['quantity'])) {
        $id = $_POST['id'];
        $name = $_POST['name'];
        $price = $_POST['price'];
        $quantity = $_POST['quantity'];

        try {
            // Connect to the database
            $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            // Update the cart item with the new quantity or perform other operations
            // Example: Update the quantity in the cart table
            $stmt = $conn->prepare("UPDATE cart SET quantity = :quantity WHERE id = :itemId");
            $stmt->bindParam(':quantity', $quantity);
            $stmt->bindParam(':itemId', $id);
            $stmt->execute();

            // Return a success response
            $response = ['success' => true];
            echo json_encode($response);
            exit; // Stop executing further code
        } catch (PDOException $e) {
            // Return an error response
            $response = ['success' => false, 'error' => $e->getMessage()];
            echo json_encode($response);
            exit; // Stop executing further code
        }
    }
}

// Return an error response for direct access or invalid requests
$response = ['success' => false, 'error' => 'Invalid request'];
echo json_encode($response);
?>

What debugging have you done so far? Does your PHP code get the correct information from your Ajax request, for example, when you var_dump($_POST)? If the error is “invalid request”, though, that suggests that your check for $_SERVER['HTTP_X_REQUESTED_WITH'] is failing.

@droopsnoot i have done var_dump() i and got array size = 0. If you say i must change HTTP header what other options should i use to allow get the right data back from the table?

I don’t know. I did a search for that header and found that most Ajax implementations should set it, so I can’t see why you’re having problems. What version of Ajax are you using?

There’s generally no need to test for an ajax request in the server-side code UNLESS that code is part of the same page as the client-side ajax code.

If all this code is on one page and you are seeing the {"success":false,"error":"Invalid request"} output at the top of the page when the page is requested, this is because the logic is incorrect. You would simply NOT have those two lines of code at the end of the php code in this case, since the request for the page is initially NOT an ajax request.

As to why you are getting the ‘Failed to add item to the cart. Please try again.’ alert, you need to look at the browser’s developer tools, network tab, response to see what the actual error being output from the php code is OR display that error text as part of the alert() text.

Next, your cart needs to store data per visitor. If you are going to use a database based cart, you need to generate a unique cart id per visitor. The simplest way of doing this is to start a session, then use the session id as the cart id.

Also, if an item isn’t already in the cart, your code won’t do anything. You should actually be using an INSERT … ON DUPLICATE KEY UPDATE … query to insert a new row of data if it doesn’t exist, or update the quantity if there is a row of data.

Did you get that by looking at an actual AJAX response, or by sticking the URL in your browser? Cause those should give you two different things.

Some very small changes will get things working on a remote file or on the same page.
As mabismad pointed out on update-cart.php you would remove that outer IF condition checking for HTTP_X_REQUESTED_WITH with the closing bracket and following lines as was suggested. If you placed this processing code on the same “cart” page then you would need to use that IF condition.

Now when you are trying to figure out WHY something doesn’t work you need to do some tests. SO make a small form to test your Processing code.

<form action="update-cart.php" method="post">
	<input type="text" name="id" value="123" />
	<input type="text" name="name" value="Product Name" />
	<input type="text" name="price" value="10.99" />
	<input type="text" name="quantity" value="1" />	
	<button type="submit" name="testsubmit" value="Submit">Submit</button>
</form>

It was easy to test and see the JSON response being echoed to the page and after changing quantity value a few times and checking that the DB was updated we can rule out that there are any problems with the processing.

SO the issue must be in the javascript. We know the response is being sent out but it is not being picked up. Why? Because we have not defined the data type format we are using to receive the response, which we have already determined is JSON. So we need to add this to the Ajax call.

dataType: 'JSON',

Now your calls are updating the Database.

Your “Success” section is looking for fa-shopping-cart then badge class and looking for the value this tag holds and increment the value by 1. You could add this tag with intial value of zero by your link name and it should increment as intended.

<i class="fas fa-shopping-cart text-primary mr-1"></i><span class="badge">0</span>Add To Cart</a>

It’s cute but doesn’t reflect the value in the database.

There are many more things to consider besides just the item, really before anything is added to the database. It gives you a starting point though so keep reading and coding.

For a slightly different approach let’s send the request to the same page and instead of saving the item to the database, let’s save it to session. In the JS as before we pick up and define the itemId and apply it to productInfo.

var productInfo = {
	id: itemId,
	mode: "add_to",
	quantity: 1
};

As the link we are using is defined by class .add-to-cart-btn I want to pass this mode in the jquery to identify the action I want to take. In this case "add_to".

The call section is much like before only you are sending to the same page. The url can be defined as the current page much like before or left out.

$.ajax({
	type: 'POST',	
	dataType: 'JSON',
	data: productInfo,
	success: function(response) {
       
	}
});

At the top of the page we add session_start(); and that wrapper we discussed.

session_start();

if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'):

endif;

Inside this we add another POST IF condition checking for all the post values being set and not empty. I want to save items and quantity to a $_SESSION['cart'] so I want to define this $_SESSION['cart'] array if it is Not Set, so I write an IF condition inside the outer conditions.

if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'):	
	if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mode']) && !empty($_POST['id']) && !empty($_POST['quantity'])):
		if(!isset($_SESSION['cart'])){$_SESSION['cart']=array();}


	endif;
endif;	

Now we can look for the 'mode' that was passed and write an IF condition to contain the action we wish to do.

//add_to
if(isset($_POST['mode']) && $_POST['mode'] ==	"add_to"):			
		
endif;

I want the ID saved to session as the array KEY and the quantity as the value. So we check if the ID key exists in the cart array and if not, set this KEY = quantity to session.

if(!array_key_exists($_POST['id'],$_SESSION['cart'])):
	$_SESSION['cart'][$_POST['id']] = $_POST['quantity'];				
endif;

If the ID key is already in the cart session we add Post qty to the session qty.

if(array_key_exists($_POST['id'],$_SESSION['cart'])):
	$_SESSION['cart'][$_POST['id']] = $_SESSION['cart'][$_POST['id']] +	$_POST['quantity'];				
endif;

Based on the session[‘cart’][id] value you define a variable as the value or zero if empty.

$q = (!empty($_SESSION['cart'][$_POST['id']]) ? $_SESSION['cart'][$_POST['id']] : 0);

And pass this ‘qty’ as your response.

$response[] = array('qty' => $q);
echo json_encode($response);
exit; // Stop executing further code

So our processing section looks like this now.

if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'):	
	if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mode']) && !empty($_POST['id']) && !empty($_POST['quantity'])):
		if(!isset($_SESSION['cart'])){$_SESSION['cart']=array();}
			
		//add_to
		if(isset($_POST['mode']) && $_POST['mode'] ==	"add_to"):			
			if(array_key_exists($_POST['id'],$_SESSION['cart'])):
				$_SESSION['cart'][$_POST['id']] = $_SESSION['cart'][$_POST['id']] +	$_POST['quantity'];				
			endif;
			if(!array_key_exists($_POST['id'],$_SESSION['cart'])):
				$_SESSION['cart'][$_POST['id']] = $_POST['quantity'];				
			endif;			
		endif; 
		 	
		$q = (!empty($_SESSION['cart'][$_POST['id']]) ? $_SESSION['cart'][$_POST['id']] : 0);			
		$response[] = array('qty' => $q);
		echo json_encode($response);
		exit; // Stop executing further code	
			
	endif;
endif;

Then down in your page your badge must also be uniquely identified for each item with the ID much like you had the ID defined. We’ll keep the css class .badge but and another name to add the ID to. It can be ‘badge’ as well.

<span class="badge badge123">0</span>

We can then finish the JS response section defining the cartBadge the itemid and update the text in this <span> with the session value that was passed back in the response.

	success: function(response) {
	var cartBadge = $('.fa-shopping-cart + .badge'+itemId);
		cartBadge.text(response[0]['qty']);	       
	}

You could modify the link text to a simple PLUS SIGN and watch your badge number increase with every click.

<a href="#" class="btn btn-sm text-dark p-0 add-to-cart-btn" id="cart-123"><i class="fas fa-shopping-cart text-primary mr-1"></i><b>+</b></a>

Now you can make another link to subtract by changing the class name being used.

<a href="#" class="btn btn-sm text-dark p-0 subtract-from-cart-btn" id="cart-125"><i class="fas fa-shopping-cart text-primary mr-1"></i><b>-</b></a>

Copy your add-to-cart-btn JS and modify it to use the subtract-from-cart-btn and change the more to mode: "subtract_from",.
In the “processing section” wrappers you can look for this “subtract_from” mode and add an IF condition to contain section of code. We want to make sure the ID is a key in the session cart array so we write a condition to check for that. Then write a condition saying IF post qty is less than cart qty and if true subtract post qty from cart qty and set this as the new value.

Another IF condition says If the post qty is equal to the cart qty we unset the item from the cart.

//subtract_from
if(isset($_POST['mode']) && $_POST['mode'] == "subtract_from"):			
	if(array_key_exists($_POST['id'],$_SESSION['cart'])):	 
		if($_POST['quantity'] < $_SESSION['cart'][$_POST['id']]):
			$_SESSION['cart'][$_POST['id']] = $_SESSION['cart'][$_POST['id']] -	$_POST['quantity'];
		endif;	
		
		if($_POST['quantity'] == $_SESSION['cart'][$_POST['id']]):
			unset($_SESSION['cart'][$_POST['id']]);
		endif;							
	endif;		
endif;

Now you have + and - links adding and subtracting from the cart.

You could also add a Remove Item link in much the same way.

<a href="#" class="btn btn-sm text-dark p-0 remove-item-cart-btn" id="cart-123"><i class="fas fa-shopping-cart text-primary mr-1"></i>Remove Item</a>

Again just copy the JS and change that class and mode. In the processing look for this mode and again check that the ID key exists in the cart array and unset the key.

//remove_item
if(isset($_POST['mode']) && $_POST['mode'] == "remove_item" && array_key_exists($_POST['id'],$_SESSION['cart'])):
	unset($_SESSION['cart'][$_POST['id']]);
endif;

You will be able to add multiple items to your cart session, change amounts or remove items. These session items and their quantities are now available if you were to go to a “View Cart” page for example where further processing could be done and an order placed where customer, order and item information would be placed into the database.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.