# Imitation Hema - Shopping Cart Logic Optimization (39)

Technical Stack  
Appgallery Connect

Development Preparation The main shopping functions of our app have been developed relatively comprehensively. Next, we will iterate and modify the logic of each function to make our program more robust and reduce logical bugs.

Function Analysis In previous development, the shopping cart function was implemented. However, during subsequent use, it was found that when adding new products, there were cases where products couldn't be added. This is mainly because in the product specification pop-up window SpecDialog, we used @Provide for the user. Here, we replace it with @State. In the shopping cart, when some or all items are not selected and the user clicks "Checkout", they can still be redirected to the order confirmation page, which is a logical issue. We need to optimize the logic for the unselected state.

Code Implementation First, optimize the addition logic in the specification pop-up window:

javascript Row(){ Text("Add to Cart") .width('70%') .borderRadius(30) .textAlign([TextAlign.Center](http://TextAlign.Center)) .fontColor([Color.Black](http://Color.Black)) .margin({top:70}) .height(40) .fontSize(18) .fontWeight(FontWeight.Bold) .backgroundColor("#FCDB29") .onClick(async ()=&gt;{ try { if (this.user==null&&this.user==undefined) { showToast("Please log in first") return } let databaseZone = [cloudDatabase.zone](http://cloudDatabase.zone)('default'); let condition = new cloudDatabase.DatabaseQuery(cart\_product\_list); condition.equalTo("productId",this.product?.id).and().equalTo("productSpecId",this.specList\[this.checkIndex\].id) let listData = await databaseZone.query(condition); let json = JSON.stringify(listData) [hilog.info](http://hilog.info)(0x0000, 'testTag', `Succeeded in upserting data, result: ${json}`); let request:CartProductList\[\]=JSON.parse(json) let cartPush = new cart\_product\_list();

if (request.length&gt;0) { let data:CartProductList=request\[0\] [cartPush.id](http://cartPush.id)\=[data.id](http://data.id); if (this.user!=null) { cartPush.user\_id=this.user!.user\_id } cartPush.productId=data.productId// Product ID cartPush.productSpecId=data.productSpecId// Specification ID cartPush.productName=data.productName// Product Name cartPush.productSpecName=data.productSpecName cartPush.productImgAddress=data.productImgAddress cartPush.buyAmount=this.addNumber+data.buyAmount// Quantity cartPush.isNeedPay=data.isNeedPay// Selected or not, default true cartPush.activityType=data.activityType// Activity type, none for now cartPush.productPrice=data.productPrice// Price cartPush.productOriginalPrice=data.productOriginalPrice// Original price cartPush.couponPrice=data.couponPrice } else { [cartPush.id](http://cartPush.id)\=Math.floor(Math.random() \* 1000000); cartPush.productId=this.product!.id// Product ID if (this.user!=null) { cartPush.user\_id=this.user!.user\_id } cartPush.productSpecId=this.specList\[this.checkIndex\].id// Specification ID cartPush.productName=this.product!.name// Product Name cartPush.productSpecName=this.specList\[this.checkIndex\].name cartPush.productImgAddress=this.product!.url// Image URL cartPush.buyAmount=this.addNumber// Quantity cartPush.isNeedPay=true// Selected or not, default true cartPush.activityType="1"// Activity type, none for now cartPush.productPrice=this.product!.price// Price cartPush.productOriginalPrice=this.product!.original\_price// Original price cartPush.couponPrice=0 }

let num = await databaseZone.upsert(cartPush); [hilog.info](http://hilog.info)(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`); if (num&gt;0) { showToast("Product added successfully") } let eventData: emitter.EventData = { data: {} };

let innerEvent: emitter.InnerEvent = { eventId: 1011, priority: emitter.EventPriority.HIGH };

emitter.emit(innerEvent, eventData); this.controller.close() } catch (err) { [hilog.info](http://hilog.info)(0x0000, 'testTag', `Failed to upsert data, error: ${err}`); } }) } .width('100%') .justifyContent([FlexAlign.Center](http://FlexAlign.Center))

Next, implement a prompt when no items are selected and prevent navigation to the order confirmation page:

javascript isAllTrue(list: CartProductList\[\]): boolean { for (const item of list) { if (item\['isNeedPay'\] === true) return true; } return false; }

If at least one item is selected, continue with the subsequent logic. On the order confirmation page, filter the passed data based on isNeedPay to only include selected items. Unselected items remain in the cart:

javascript onPageShow(): void { let params = router.getParams() as DataModel if (params!=null&¶ms.json!=undefined){ let list:CartProductList\[\]=JSON.parse(params.json) for (let i = 0; i &lt; list.length; i++) { if (list\[i\].isNeedPay) { this.productList.push(list\[i\]) } } }

let params1 = router.getParams() as AddressModel if (params1!=null&¶ms1.address!=undefined){ this.addressInfo=JSON.parse(params1.address) } }

This completes the first round of optimization for the shopping cart logic.

Continuing to identify logical gaps, it was found that when selecting or deselecting items, the userId was not included in the data updates. This caused the data to lose the userId, resulting in these items disappearing from the cart when queried later, as queries are based on the user's userId. The corresponding logic is added here:

javascript Image(item.isNeedPay?$r('[app.media](http://app.media).cart\_check'):$r('[app.media](http://app.media).cart\_no\_check')) .height(20) .width(20) .objectFit(ImageFit.Contain) .onClick(async ()=&gt;{ let cartPush = new cart\_product\_list(); let data:CartProductList=item [cartPush.id](http://cartPush.id)\=[data.id](http://data.id); cartPush.user\_id=this.user!.user\_id cartPush.productId=data.productId// Product ID cartPush.productSpecId=data.productSpecId// Specification ID cartPush.productName=data.productName// Product Name cartPush.productSpecName=data.productSpecName cartPush.productImgAddress=data.productImgAddress cartPush.buyAmount=data.buyAmount// Quantity cartPush.activityType=data.activityType// Activity type, none for now cartPush.productPrice=data.productPrice// Price cartPush.productOriginalPrice=data.productOriginalPrice// Original price cartPush.couponPrice=data.couponPrice if (item.isNeedPay) { item.isNeedPay=false this.productList\[index\] = new CartProductList([item.id](http://item.id),item.user\_id, item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) cartPush.isNeedPay=false } else { item.isNeedPay=true this.productList\[index\] = new CartProductList([item.id](http://item.id),item.user\_id, item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) cartPush.isNeedPay=true }

let num = await databaseZone.upsert(cartPush); [hilog.info](http://hilog.info)(0x0000, 'TAG', `Data updated: ${num}`); this.getCountPrice() })

Further down, it was found that when adding or reducing the quantity of products, the userId was still not handled. The corresponding logic is added here:

javascript Row(){ Text("-") .textAlign([TextAlign.Center](http://TextAlign.Center)) .border({width:0.5,color:Color.Gray}) .fontSize(14) .height(20) .padding({left:7,right:7}) .fontColor([Color.Black](http://Color.Black)) .onClick(async ()=&gt;{ if (item.buyAmount==1) { showToast("Minimum quantity reached") } else { item.buyAmount--

let cartPush = new cart\_product\_list(); let data:CartProductList=item [cartPush.id](http://cartPush.id)\=[data.id](http://data.id); cartPush.user\_id=this.user!.user\_id cartPush.productId=data.productId// Product ID cartPush.productSpecId=data.productSpecId// Specification ID cartPush.productName=data.productName// Product Name cartPush.productSpecName=data.productSpecName cartPush.productImgAddress=data.productImgAddress cartPush.buyAmount=item.buyAmount// Quantity cartPush.activityType=data.activityType// Activity type, none for now cartPush.productPrice=data.productPrice// Price cartPush.productOriginalPrice=data.productOriginalPrice// Original price cartPush.couponPrice=data.couponPrice cartPush.isNeedPay=data.isNeedPay

let num = await databaseZone.upsert(cartPush); [hilog.info](http://hilog.info)(0x0000, 'TAG', `Data updated: ${num}`);

this.productList\[index\] = new CartProductList([item.id](http://item.id), item.user\_id,item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) this.getCountPrice() } }) .borderRadius({topLeft:5,bottomLeft:5})

Text(item.buyAmount+"") .textAlign([TextAlign.Center](http://TextAlign.Center)) .fontColor([Color.Black](http://Color.Black)) .fontSize(14) .height(20) .padding({left:10,right:10}) .border({width:0.5,color:Color.Gray})

Text("+") .textAlign([TextAlign.Center](http://TextAlign.Center)) .fontColor([Color.Black](http://Color.Black)) .fontSize(14) .height(20) .padding({left:7,right:7}) .onClick(async ()=&gt;{ item.buyAmount++ let cartPush = new cart\_product\_list();

let data:CartProductList=item [cartPush.id](http://cartPush.id)\=[data.id](http://data.id); cartPush.user\_id=this.user!.user\_id cartPush.productId=data.productId// Product ID cartPush.productSpecId=data.productSpecId// Specification ID cartPush.productName=data.productName// Product Name cartPush.productSpecName=data.productSpecName cartPush.productImgAddress=data.productImgAddress cartPush.buyAmount=item.buyAmount// Quantity cartPush.activityType=data.activityType// Activity type, none for now cartPush.productPrice=data.productPrice// Price cartPush.productOriginalPrice=data.productOriginalPrice// Original price cartPush.couponPrice=data.couponPrice cartPush.isNeedPay=data.isNeedPay

let num = await databaseZone.upsert(cartPush); [hilog.info](http://hilog.info)(0x0000, 'TAG', `Data updated: ${num}`); this.productList\[index\] = new CartProductList([item.id](http://item.id), item.user\_id,item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) this.getCountPrice() }) .border({width:0.5,color:Color.Gray}) .borderRadius({topRight:5,bottomRight:5}) } .justifyContent(FlexAlign.SpaceBetween)

At this point, the shopping cart has become relatively robust.
