onflow-cadence

Can't find a way to write a transaction to add items in my Grocery resource


I've a resource inside a resource and I've added a function to create a collection and to add items in it. I'm not quite sure how to write a transaction for it. Here's the contract and the transaction I wrote.

pub contract Crash{

    pub resource Grocery{
        pub var grocery: String
        pub var units: Int
        pub var price: UFix64

        init(_grocery: String, _units: Int, _price: UFix64) {
              self.grocery = _grocery
              self.units = _units
              self.price = _price
        }
    }

    pub resource interface InventoryPublic{
        pub var items: @{UInt64: Grocery}
    }

    pub resource Inventory: InventoryPublic{
        pub var items: @{UInt64: Grocery}
        init(){
                self.items <- {}
        }

        destroy(){
            destroy self.items
        }
    }

    pub fun createInventory(): @Inventory{
            return <- create Inventory()
    }

    pub fun addItems(name: String, nos: Int, price: UFix64): @Grocery{
            return <- create Grocery(_grocery: name,_units : nos, _price: price)
    }

}
 

here are the two transactions

import Crash from 0xf8d6e0586b0a20c7

transaction{
    prepare(acct: AuthAccount){
        acct.save(<- Crash.createInventory(), to: /storage/Inv1)

    }

    execute{
        log("Inventory Created!")
    }
}

-------------------------------------------------------------------
import Crash from 0xf8d6e0586b0a20c7

transaction{
    prepare(acct: AuthAccount){
        
        let GroceryReference = acct.borrow<&Crash.Inventory>(from: /storage/Inventory2)
                            ?? panic("No Items found!")

        


    }

    execute{
        log("Item Added!")
    }
}

I've created an Inventory to collect my groceries. I need a way to add items into my Grocery resource. Please Help :(


Solution

  • It looks like you need to add a function that takes in a Grocery resource and adds it to your dictionary:

    pub resource Inventory: InventoryPublic {
         pub var items: @{UInt64: Grocery}
         
         // will add a new item into the dictionary.
         // maps the `uuid` of the item
         // to the item itself.
         pub fun addItem(item: @Grocery) {
            self.items[item.uuid] <-! item
         }
    
         init() {
              self.items <- {}
         }
    
         destroy() {
              destroy self.items
         }
    }
    

    Once you add this, your transaction becomes quite easy because you can simply create a new grocery item, and call the addItem function on your inventory reference.

    import Crash from 0xf8d6e0586b0a20c7
    
    transaction{
        prepare(acct: AuthAccount){
            
            let inventoryRef = acct.borrow<&Crash.Inventory>(from: /storage/Inventory2)
                                ?? panic("No Items found!")
            let item <- Crash.addItems(...)
            inventoryRef.addItem(item: <- item)
        }
    
        execute{
            log("Item Added!")
        }
    }