Skip to main content
Participant
February 14, 2011
Question

Persistant component in session scope Calling functions from cfm page

  • February 14, 2011
  • 1 reply
  • 896 views

Hi, (Using Coldfusion 9.01 Standard)

Ik have slight problem using a persistent component in the session scope. i'm using inside the component a global called this.cartarray where all articles are stored on an user session. Multiple functions are declared in the component that manipulates the this.cartarray. One of the functions is converting the array to a Query object for easy showing on a cfm page. Example: Session.myShoppingCart = myShoppingCart.cfc

<cfcomponent hint="ShoppingCart">

     <!--- global definition --->

     <cfset This.Cartarray = ArrayNew(1)>

     <cffunction name="List">
          <cfset q = QueryNew("CartItemID,ItemNo")>
          <cfset var localCartArray = arrayNew(1)>
          <cfset localCartArray = This.CartArray>
          <cfloop from="1" to="#ArrayLen(localCartArray)#" index="i">
              <cfset QueryAddRow(q)>
              <cfset QuerySetCell(q, "CartItemID", localCartArray.CartItemID)>
              <cfset QuerySetCell(q, "ItemNo", localCartArray.ItemNo)>  
          </cfloop>
          <cfreturn q>
     </cffunction>

     <cffunction name="EmptyCart">

          <cfset ArrayClear(This.CartArray)>

     </cffunction>
</component>


Here the example of the myShoppingCart.cfm

<!--- On the Beginning --->

<cfset var getCart = Session.myShoppingCart.List()>

<!--- After that the manipulate function in case of a form submit --->

<cfif structKeyExists(FORM,"X") AND FORM.X eq 1>

  <cfset temp = Session.myShoppingCart.EmptyCart()>

</cif>

<!--- --->

<!--- Viewing the Cart --->

<cfoutput>

     <table>

          <tr>

               <th>CartItemID</th>

               <th>ItemNo</th>

          </tr>

          <cfloop query="getCart">

                <tr>

                     <td>#CartItemID#</td>

                     <td>#ItemNo#</td>  

                </tr>      

          </cfloop>

     </table>

</cfoutput>

<!--- --->  

</cfloop>


What is wrong with the flow because i get an Row number 0 Out of bounds exception using the List() function (On QuerySetCell).

Thanks in advance,

Chris

    This topic has been closed for replies.

    1 reply

    BKBK
    Community Expert
    Community Expert
    February 14, 2011

    You get the exception because there is as yet no elemet in the cart array. I also expected to see something like

    <!---  Use no var outside a function --->
    <cfset session.myShoppingCart = createobject("component","dotted.path.to.ShoppingCart.component")>
    <cfset getCart = Session.myShoppingCart.List()>

    Participant
    February 15, 2011

    Thank you,

    but it wasn't it, i gave a stripped version of the myShoppingCart.cfc.

    The Session myshoppingCart is created in the application.cfc on the OnSessionStart() so that's not the problem.

    The extra function to add something to the cart is this:

    <cffunction name="Add" access="public">

         <cfargument name="CartItemID" required="true">

         <cfargument name="ItemNo" required="true">

         <cfif GetCartPos(CartItemID) eq 0>

              <cfset CartItem = StructNew()>
              <cfset CartItem.CartItemID = Arguments.CartItemID>
              <cfset CartItem.ItemNo = Arguments.ItemNo>
              <cfset ArrayAppend(This.CartArray, CartItem)>    

         <cfelse>

            <cfset CartItem = This.CartArray[GetCartPos(CartItemID)]>

            <cfset CartItem.CartItemID = Arguments.CartItemID>
            <cfset CartItem.ItemNo = Arguments.ItemNo>

         </cfif>    

    </cffunction>

    <cffunction name="GetCartPos" returntype="numeric"> 
         <cfargument name="CartItemID" type="string" required="true"> 
         <cfset CurrentArrayPos = 0>
         <cfloop from="1" to="#ArrayLen(This.CartArray)#" index="i">
              <cfif This.CartArray.CartItemID EQ Arguments.CartItemID>   
                   <cfset CurrentArrayPos = i>
                   <cfbreak>   
              </cfif>
         </cfloop>
         <cfreturn CurrentArrayPos>
    </cffunction>

    But Question really is because it works most of the time, but sometimes gives the error given in the first post, and i wonder if i'm doing the right flow. Or i have to keep something in mind. its like the cartarray changed the same time when i convert the array to a query.

    BKBK
    Community Expert
    Community Expert
    February 15, 2011

    OK, I understand. However, the function list() has no argument and receives no data. So there could be occasions when the local query and array in it are empty.

    If you're sure data always comes in through the public array variable, then rearranging the code like this might help

    <cfset QueryAddRow(q,ArrayLen(localCartArray))>

    <cfloop from="1" to="#ArrayLen(localCartArray)#" index="i">
        <cfset QuerySetCell(q, "CartItemID", localCartArray.CartItemID, i)>
        <cfset QuerySetCell(q, "ItemNo", localCartArray.ItemNo, i)>  
    </cfloop>