1

I have a shopping cart array stored in a session:Screen Shot of Shopping Cart Array

I give my user the ability to select all items to delete or select individual items via a checkbox.

I am sending the array index via form post to arrayDeleteAt.

Now if I select the bottom 3 items, it does not delete it.

Here is my delete code:

<cfif isDefined("form.leadId") AND  listLen(form.leadId)>
  <cfloop from="#listLen(form.leadId)#" to="1" step="-1" index="i">
    <cfset temp = arrayDeleteAt(session.shoppingcart, #i#)>
  </cfloop> 
</cfif>
2
  • 2
    Since you are not using the result, may as well remove temp. ie <cfset arrayDeleteAt(session.shoppingcart, i)> Commented Aug 18, 2011 at 23:35
  • 1
    note that Leigh also removed the hash signs because they are not needed ... ColdFusion will already evaluate i without them. Commented Aug 22, 2011 at 18:28

3 Answers 3

7

You are going to have more issues with this method of managing your cart. After using ArrayDeleteAt the array's indexes will be recalculated, so when you will most likely delete the wrong item from the array, or you can get an error when you try and delete an item that is out of bounds.

Is see that you are trying to get around this by working backwards through your list, and Dan is right for what your issue is with the code above, but if the list is passed in in an incorrect order then you are in a world of hurt.

I would suggest instead of using an array, use a struct with a surrogate key, such as a UUID, then delete items by that key.

Sign up to request clarification or add additional context in comments.

Comments

5

The problem is that you're deleting at the position of the counter, and not the form field that's being passed in. Try this instead:

<cfset temp = arrayDeleteAt(session.shoppingcart, ListGetAt(FORM.leadID, i) />

UPDATE: To get around the issue Tyler mentioned, you can convert your list of indexes from FORM.leadID to an Array using ListToArray and then ArraySort to get them in the order necessary to make sure your deletes are correct.

While my answer does fix your immediate problem, you would definitely be better off following Tyler's advice and using a key for each item in the cart to make sure you're managing the one you actually think you're supposed to be managing :)

Comments

0

In CF 10 or Railo 4, this can be done using the most recent version of the Underscore.cfc library:

<cfscript>
if (structKeyExists(form, 'leadId') && listlen(form.leadId)) {
    _ = new Underscore();

    variables.shoppingCart = duplicate(session.shoppingCart);

    variables.newCart = _.reject(variables.shoppingCart, function(val, index){
        return _.include(form.leadId, index);
    });
}
</cfscript>

<cfif structKeyExists(variables, "newCart") >
    <cflock scope="session" type="exclusive" timeout="10">
        <cfset session.shoppingCart = variables.newCart>
    </cflock>
</cfif>

You'll see that I'm copying the shopping cart into the variables scope, editing it, then copying it back (with a lock) if necessary. I would've done this all in cfscript if it were possible to write cflocks in cfscript.

(Disclaimer: I wrote Underscore.cfc)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.