The kitty Catalogue - Did I miss something?

In the “Assignment, Breeding Front End” lesson, Filip already has a Catalogue page and a Factory page, I believe. He goes on and talks about it as if we had lessons about this. Did I miss some lessons? I don’t see these anywhere in the Ethereum Dapp Programming course…

1 Like

The Catalogue and Factory was mean to be an assignment, so the idea is that the students are challenged to made them by themselves :nerd_face:

Still you can get help over the forum if you need it :slight_smile:

Carlos Z

1 Like

Hello Carlos, thank you - it was not very clear - I never saw or heard Philip saying that - though I get it.
Thank you.

what is the advised way to retrieve all currently owned kitties to display in the Catalogue ?

is the correct way to subscribe to Transfer event … and get list of all transfers to current address .

ie. to do this each time a page is loaded or a relevant action occurs ?

You should tag Carlos like @thecil so he can respond. I personally followed the code form Filip. I asked my mentor for it. The catalogue can use one of the functions from the kitties contract like totalSuply and the, I think it was called get all tokens from owner function. It used a for loop to transfer al the kittens form owner to a mapping . It’s in the course.

The transfers are done with the emit commands which are also in the videos. You use those with web3 so you can read them and use them in your app

I was thinking of using getPastEvents but the problem with that is that I may no longer be the owner of these cats if I transferred them on to someone else:

function getAllKittiesOwned(){

    instance.getPastEvents('Transfer', {
        to : account
    }).then(results => {
        console.log(results)
    }).catch(err => {
        console.log(err)
      });
}

hey @Emmett ! In order to retrieve all your Kitties, you can query owned ids array from the kittyContract.sol and use the getKitty() function to iterate over owned ids.
To query this array of owned ids, you can include it like a mapping into your contract like:

mapping (address => uint256[]) public ownedKitties;

And use it into the create kitty and transfer, functions like:

ownedKitties[msg.sender].push(newId)

Remember also to delete from user mapping when is transfed by the buy function.

Let me know if its work.

in the end I did this… which although not so efficient works for now…

const getAllKittiesOwned = async() => {

    try{
        let _ownedKitties = [];
        const events = await instance.getPastEvents('Transfer', {
            to : account
        })

        //for each event, check if we still own the token otherwise discard

        for(var i =0; i< events.length; i++){
            console.log("checking if user still owns ", events[i].returnValues["tokenId"])
            const owner = await instance.methods.ownerOf(events[i].returnValues["tokenId"]).call()
            if( owner.toLowerCase() == account.toLowerCase()){
                const kitty = await instance.methods.getKitty(events[i].returnValues["tokenId"]).call()
                console.log("kitty:" +kitty)
                _ownedKitties.push(kitty)
            }
            
        }
        ownedKitties = _ownedKitties;

    }catch(err){
        console.error(err)
    }

}

despite creating new kitties… for some reason instance.getPastEvents('Transfer', { to : account }) always seems to return only one event , when it should be returning me one for each kitty I created

ok figured it out… had filter and fromBlock /toBlock incorrect:
this works now albeit inefficient:

const getAllKittiesOwned = async() => {

    try{
        let _ownedKitties = [];
        const events = await instance.getPastEvents('Transfer', {
            filter: {to : account},
            fromBlock: 0,
            toBlock: 'latest'
        })

        //for each event, check if we still own the token otherwise discard
        if(events){
            for(var i =0; i< events.length; i++){
                const tokenId = events[i].returnValues["tokenId"]
                console.log("checking if user still owns ", )
                const owner = await instance.methods.ownerOf(tokenId).call()
                if( owner.toLowerCase() == account.toLowerCase()){
                    let kitty = await instance.methods.getKitty(tokenId).call()
                    kitty.tokenId = tokenId
                    console.log("kitty:" +kitty)
                    _ownedKitties.push(kitty)
                }
                
            }
            ownedKitties = _ownedKitties;
        }
        

    }catch(err){
        console.error(err)
    }

}
1 Like