Don'ja just hate finally nailing a problem only to find someone has a better way of doing it? (LOL!)
now I know how Collingwood feels after last Saturday. thanx Spike, Mark et al. Me crawl back cave now... cheers barry.b -----Original Message----- From: Spike [mailto:[EMAIL PROTECTED] Sent: Monday, 29 September 2003 2:48 PM To: CFAussie Mailing List Subject: [cfaussie] Re: CFC error: "Method selection Exception" (was: Shopping carts: Arr ays Vs Structs) I'm not sure you've got this whole shopping cart thing clear. I've put together a quick example of how I'd go about it. Save the two files below as shoppingcart.cfc and callingpage.cfm in the same directory. Watch out for line wrapping problems. Spike shoppingcart.cfc ************************************************************ <cfcomponent displayname="shoppingCart"> <cfset init()> <cffunction name="init" access="public" output="false" returntype="boolean" hint="Initializes the cart if it has not been initialized yet"> <cfif not isDefined('instance')> <cfset instance = structNew()> <cfset instance.aItems = arrayNew(1)> <cfset instance.timestamp = Now()> <cfset instance.IDs = ""> </cfif> <cfreturn true> </cffunction> <cffunction name="addItem" access="public" output="false" returntype="boolean" hint="Adds an item to the cart. A cart item is a structure with any number of keys. The only required key is 'ID' which must be uniqe for every item in the cart."> <cfargument name="item" type="struct" required="yes"> <!--- Make sure the item has an id and that the id is unique ---> <cfif not structKeyExists(arguments.item,'id')> <cfthrow type="shoppingCart.invalidItem" message="The item does not have an id key" detail="All items added to the shopping cart must have a unique ID key to ensure that duplicate items cannot be created and multiple items are not deleted if the user refreshes the page."> </cfif> <cfif listFind(instance.IDs,arguments.item.id)> <cfthrow type="shoppingCart.invalidItem" message="The item does not have a unique id key" detail="All items added to the shopping cart must have a unique ID key to ensure that duplicate items cannot be created and multiple items are not deleted if the user refreshes the page."> </cfif> <cfset instance.IDs = listAppend(instance.IDs,arguments.item.id)> <cfreturn arrayAppend(instance.aItems,duplicate(arguments.item))> </cffunction> <cffunction name="removeItem" access="public" output="false" returntype="boolean" hint="Removes an item from the cart based on the ID passed in."> <cfargument name="id" type="string" required="yes"> <cfset var index = ""> <!--- Make sure the item has an id and that the id is unique ---> <cfif NOT listFind(instance.IDs,arguments.id)> <cfthrow type="shoppingCart.invalidItemID" message="The item you tried to delete does not exist" detail="The item id passed to the removeItem() method does not correspond to any items in the cart."> </cfif> <cfset index = listFind(instance.IDs,arguments.id)> <cfreturn arrayDeleteAt(instance.aItems,index)> </cffunction> <cffunction name="getCartItems" access="public" output="false" returntype="array" hint="Returns an array of items in the order they were added to the cart"> <cfreturn instance.aItems> </cffunction> <cffunction name="getTimeStamp" access="public" output="false" returntype="date" hint="Returns the timestamp when the cart was created"> <cfreturn instance.timestamp> </cffunction> <cffunction name="clearCart" access="public" output="false" returntype="boolean" hint="Clears the cart removing all items"> <cfset instance.aItems = arrayNew(1)> <cfreturn true> </cffunction> </cfcomponent> ***************************************************************** callingpage.cfm ***************************************************************** <cfapplication name="cartexample" sessionmanagement="yes"> <cfset session.cart = createObject('component','shoppingcart')> <cfdump var="#session.cart.getCartItems()#" label="After Initialization"> <cfset firstID = createUUID()> <cfset myItem = structNew()> <cfset myItem.priceperunit = 120> <cfset myItem.name = "Some useful thing"> <cfset myItem.quantity = 2> <cfset myItem.id = firstID> <cfset session.cart.addItem(myItem)> <cfdump var="#session.cart.getCartItems()#" label="After adding first item"> <cfset secondID = createUUID()> <cfset myItem = structNew()> <cfset myItem.priceperunit = 30> <cfset myItem.name = "Another useful thing"> <cfset myItem.quantity = 1> <cfset myItem.id = secondID> <cfset session.cart.addItem(myItem)> <cfdump var="#session.cart.getCartItems()#" label="After adding second item"> <cfset thirdID = createUUID()> <cfset myItem = structNew()> <cfset myItem.priceperunit = 10> <cfset myItem.name = "A third useful thing"> <cfset myItem.quantity = 25> <cfset myItem.id = thirdID> <cfset session.cart.addItem(myItem)> <cfdump var="#session.cart.getCartItems()#" label="After adding third item"> <cfset session.cart.removeItem(secondID)> <cfdump var="#session.cart.getCartItems()#" label="After removing second item"> <cfset session.cart.clearCart(secondID)> <cfdump var="#session.cart.getCartItems()#" label="After clearing cart"> ****************************************************************** Beattie, Barry wrote: > thanx again Mark. It's leading to a couple of more questions, I'm afraid... > > > >>>Neither - you aren't calling the method on a CFC. You are trying to call > > it on a > struct. > > you've confused me now. The only thing I've done different from usual is not > used an argument in invoking the component and the CFC not having > properties. Perhaps I'm getting confused with CFC interfaces seemimg to be > like structs themselves, not like real objects eg: COM (actually, they feel > more like VBScript classes than objects). > > > >> <cfproperty name="aProducts" type="array"> >> >> <!--- contructor ---> >> <cfscript> >> //place to store my carts >> this.aProducts = ArrayNew(1); >> </cfscript> > > > Ummm... why the array? is this for an array of structures or a struct of > arrays? > > > >><!--- application.cfm ---> >> >><cfif NOT isDefined("session.cart")> >><cfscript> >> session.cart = CreateObject(type, "com.Cart"); >></cfscript> >></cfif> > > >>- Hence all data is stored in the CFC - and is specific TO the CFC, and > > nothing else (which gives lower coupling). > > so the instance is stored in the session? How does session.cart get updated > with new cart contents within the CFC? and what would you do if cookies or a > db have to be used instead? you've made a good point about the loose > coupling but it's satisfying the other side (tight cohesion) that worries me > on this bit. > > thanx > barry.b > > > -----Original Message----- > From: Mark M [mailto:[EMAIL PROTECTED] > Sent: Monday, 29 September 2003 12:18 PM > To: CFAussie Mailing List > Subject: [cfaussie] Re: CFC error: "Method selection Exception" (was: > Shopping carts: Arr ays Vs Structs) > > > >>1) so I'm calling the method wrong? or not invoking the component >>correctly? > > > Neither - you aren't calling the method on a CFC. You are trying to call it > on a > struct. Hence the error. Dump out the 'objCart' variable, and I think you > will find > what I mean. > > >>2) >> A shopping cart should only manage the shopping cart. It >>shouldn't >>look at if it exists or not. >> >>yes good point but I was trying to tie the storage of cart data >>totally into >>the CFC. IMHO only the CFC should care how the cart data is stored >>and not >>be dependant on other files. The CFC becomes the data store >>interface. If >>the chosen storage doesn't exist, create it. > > > That is fine - however I would have built it like this: > > > <!--- component cart ---> > <cfcomponent displayname="Cart"> > > <cfproperty name="aProducts" type="array"> > > <!--- contructor ---> > <cfscript> > //place to store my carts > this.aProducts = ArrayNew(1); > </cfscript> > > <cffunction name="AddToCart" access="public" output="false"> > <cfargument name="key" required="true" type="numeric"> > <cfargument name="value" required="true" type="numeric"> > <!--- add the item ---> > <cfscript> > StructInsert(this.aProducts, arguments.key, > arguments.value); > </cfscript> > </cffunction> > > </cfcomponent> > > > <!--- application.cfm ---> > > <cfif NOT isDefined("session.cart")> > <cfscript> > session.cart = CreateObject(type, "com.Cart"); > </cfscript> > </cfif> > > - Hence all data is stored in the CFC - and is specific TO the CFC, and > nothing > else (which gives lower coupling). > > HTH > > Mark > > --- > You are currently subscribed to cfaussie as: [EMAIL PROTECTED] > To unsubscribe send a blank email to [EMAIL PROTECTED] > > MX Downunder AsiaPac DevCon - http://mxdu.com/ > > --- You are currently subscribed to cfaussie as: [EMAIL PROTECTED] To unsubscribe send a blank email to [EMAIL PROTECTED] MX Downunder AsiaPac DevCon - http://mxdu.com/ --- You are currently subscribed to cfaussie as: [EMAIL PROTECTED] To unsubscribe send a blank email to [EMAIL PROTECTED] MX Downunder AsiaPac DevCon - http://mxdu.com/
