mismatched types. expected `NonFungibleToken.NFT`, got `NonFungibleToken.NFT?

97 Views Asked by At

While deploying this contract I am getting an error "mismatched types. expected NonFungibleToken.NFT, got `NonFungibleToken.NFT?".Can anyone help me why the error showing up in my code.

pub contract MetaVEvents:NonFungibleToken{ pub let creator:Address pub let nxmAddress:Address pub let projId:UInt64 pub var totalSupply: UInt64

    pub let ticketCount:{UInt64:UInt64}

pub event ContractInitialized()
pub event Withdraw(id: UInt64, from: Address?)
pub event Deposit(id: UInt64, to: Address?)

pub let CollectionStoragePath: StoragePath
pub let CollectionPublicPath: PublicPath



   init(_creator:Address,_nxmAddress:Address,_projId:UInt64){
    self.creator = _creator
    self.nxmAddress = _nxmAddress
    self.projId = _projId
     // Initialize the total supply
    self.totalSupply = 0

    self.ticketCount ={}

     // Set the named paths
    self.CollectionStoragePath = /storage/MetaVEventsNftCollections
    self.CollectionPublicPath = /public/MetaVEventsNftCollections

    emit ContractInitialized()
   }

   pub resource NFT:NonFungibleToken.INFT{
    pub let id:UInt64
    pub let maxCount:UInt64
    pub let metadata:{String:String}

    init(_nftId:UInt64,_maxCount:UInt64,_metadata:{String : String}){
      self.id = _nftId
      self.maxCount =_maxCount
      self.metadata =_metadata

    }
   }

     pub resource interface CollectionPublic {
pub fun borrowEntireNFT(id: UInt64): &MetaVEvents.NFT

}

  pub resource Collection:NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic,CollectionPublic{
    pub var ownedNFTs: @{UInt64:NonFungibleToken.NFT}

    pub fun deposit(token:@NonFungibleToken.NFT){
      let myToken <- token as! @MetaVEvents.NFT
      emit Deposit(id:myToken.id,to:self.owner?.address)
      self.ownedNFTs [myToken.id] <-! myToken

    }

    pub fun withdraw(withdrawID:UInt64):@NonFungibleToken.NFT{
        let withdrawNft <- self.ownedNFTs.remove(key:withdrawID) ?? panic("This nft id doesn't exist")
       emit Withdraw(id:withdrawID,from:self.owner?.address)
       return <- withdrawNft
    }


    pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
       return &self.ownedNFTs[id] as &NonFungibleToken.NFT
   }

    pub fun borrowEntireNFT(id: UInt64): &MetaVEvents.NFT {
  let reference = &self.ownedNFTs[id]  as auth &NonFungibleToken.NFT
  return reference as! &MetaVEvents.NFT
}

    pub fun getIDs(): [UInt64] {
      return self.ownedNFTs.keys
    }



    init(){
      self.ownedNFTs <- {}
    }

    destroy(){
      destroy self.ownedNFTs
   }

}

  pub fun createEmptyCollection():@Collection{
    return <- create Collection()
  }
  pub fun mint(id:UInt64,maxCount:UInt64,metadata:{String:String}):@MetaVEvents.NFT{
    return <- create NFT(_nftId:id,_maxCount:maxCount,_metadata:metadata)
  }

 pub fun mintEvent(eventId:UInt64,maxCount:UInt64,cid:{String:String}):@MetaVEvents.NFT{
   return <- MetaVEvents.mint(id:eventId,maxCount:maxCount,metadata:cid)
 }

While I am trying to deploy this contract I am getting this compilation error in the borrowNFT function

3

There are 3 best solutions below

0
j00lz On

You are getting an optional from the borrow function dictionary lookup as it could return nil if there is no token there

0
Nasir On

The error message "borrowNFT" and "borrowEntireNFT" cannot borrow because of their types, is likely caused by the secure cadence version. To fix this, you should follow the newly secure cadence features described in the post. https://forum.onflow.org/t/breaking-changes-coming-with-secure-cadence-release/3052/20 Also your borrowNFT code function will be like this,

pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
    return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
}

This code ensures that you are returning a borrowed reference to the NFT object, which is required by the secure cadence version. Be sure to follow the secure cadence features described in the post to ensure that your code is up to date with the latest version.

1
Jacob Tucker On

As mentioned here already, dictionary references now return optionals.

So, code that looks like this will give an error: return &self.ownedNFTs[id] as &NonFungibleToken.NFT

It must look like this instead: return &self.ownedNFTs[id] as &NonFungibleToken.NFT?

If you don't want to return an optional type, you can force unwrap the optional: (return &self.ownedNFTs[id] as &NonFungibleToken.NFT?)!