Token Contract is not defined at mint NFT await tokenContract.methods.createItem(metadataUrl).send({from: ethereum.selectedAddress});

Hi, I am doing rarible clone… Website was working fine a few months ago but Now it is showing errors may be moralis updated some of the definitions… I am facing these erros:

main.js:9 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘Contract’)
at init (main.js:9:41)
init @ main.js:9
await in init (async)
(anonymous) @ main.js:385

main.js:209 Uncaught (in promise) ReferenceError: tokenContract is not defined
at mintNft (main.js:209:21)
at HTMLButtonElement.createItem (main.js:169:25)

These three images show the lines of code where it is giving an error… Please help with this Thanks.

Yes there has been a change in the sdk. web3 is updated to ethers.
you need to change web3.eth.Contract to ethers.Contract

Refer the below docs for more details.

https://docs.moralis.io/moralis-dapp/web3/web3#get-the-ethersjs-library

1 Like

Still showing the same error… I will be very thankful if you can run the code and do the possible fixes.
Here is the code

//main.js
Moralis.initialize(“nipQjqrhBKRKgImhcmsHXfZPpFjECeNXVFAUtDuC”);
Moralis.serverURL = ‘https://o8wnxho996mr.usemoralis.com:2053/server’
const TOKEN_CONTRACT_ADDRESS = “0x2F3B7F18ad103A35a22188807Cc91b0Ab97f3192”;
const MARKETPLACE_CONTRACT_ADDRESS = “0xe867FD1C142480d17DB9de36aeBE4C82d791365D”;

init = async () => {
hideElement(userItemsSection);
window.web3 = await Moralis.enableWeb3();
window.tokenContract = new web3.ether.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);
window.marketplaceContract = new web3.ether.Contract(marketplaceContractAbi, MARKETPLACE_CONTRACT_ADDRESS);
initUser();
loadItems();

const soldItemsQuery = new Moralis.Query('SoldItems');
const soldItemsSubscription = await soldItemsQuery.subscribe();
soldItemsSubscription.on("create", onItemSold);

const itemsAddedQuery = new Moralis.Query('ItemsForSale');
const itemsAddedSubscription = await itemsAddedQuery.subscribe();
itemsAddedSubscription.on("create", onItemAdded);

}

onItemSold = async (item) => {
const listing = document.getElementById(item-${item.attributes.uid});
if (listing){
listing.parentNode.removeChild(listing);
}

user = await Moralis.User.current();
if (user){
    const params = {uid: `${item.attributes.uid}`};
    const soldItem = await Moralis.Cloud.run('getItem', params);
    if (soldItem){
        if (user.get('accounts').includes(item.attributes.buyer)){
            getAndRenderItemData(soldItem, renderUserItem);
        }

        const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
        if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
      
    }

}

}

onItemAdded = async (item) => {
const params = {uid: ${item.attributes.uid}};
const addedItem = await Moralis.Cloud.run(‘getItem’, params);
if (addedItem){
user = await Moralis.User.current();
if (user){
if (user.get(‘accounts’).includes(addedItem.ownerOf)){
const userItemListing = document.getElementById(user-item-${item.tokenObjectId});
if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);

            getAndRenderItemData(addedItem, renderUserItem);
            return;
        }
    }
    getAndRenderItemData(addedItem, renderItem);
}

}

initUser = async () => {
if (await Moralis.User.current()){
hideElement(userConnectButton);
showElement(userProfileButton);
showElement(openCreateItemButton);
showElement(openUserItemsButton);
loadUserItems();
}else{
showElement(userConnectButton);
hideElement(userProfileButton);
hideElement(openCreateItemButton);
hideElement(openUserItemsButton);
}
}

login = async () => {
try {
await Moralis.Web3.authenticate();
initUser();
} catch (error) {
alert(error)
}
}

logout = async () => {
await Moralis.User.logOut();
hideElement(userInfo);
initUser();
}

openUserInfo = async () => {
user = await Moralis.User.current();
if (user){
const email = user.get(‘email’);
if(email){
userEmailField.value = email;
}else{
userEmailField.value = “”;
}

    userUsernameField.value = user.get('username');

    const userAvatar = user.get('avatar');
    if(userAvatar){
        userAvatarImg.src = userAvatar.url();
        showElement(userAvatarImg);
    }else{
        hideElement(userAvatarImg);
    }

    $('#userInfo').modal('show');
}else{
    login();
}

}

saveUserInfo = async () => {
user.set(‘email’, userEmailField.value);
user.set(‘username’, userUsernameField.value);

if (userAvatarFile.files.length > 0) {
    const avatar = new Moralis.File("avatar1.jpg", userAvatarFile.files[0]);
    user.set('avatar', avatar);
}

await user.save();
alert("User info saved successfully!");
openUserInfo();

}

createItem = async () => {

if (createItemFile.files.length == 0){
    alert("Please select a file!");
    return;
} else if (createItemNameField.value.length == 0){
    alert("Please give the item a name!");
    return;
}

const nftFile = new Moralis.File("nftFile.jpg",createItemFile.files[0]);
await nftFile.saveIPFS();

const nftFilePath = nftFile.ipfs();
const nftFileHash = nftFile.hash();

const metadata = {
    name: createItemNameField.value,
    description: createItemDescriptionField.value,
    image: nftFilePath,
    
    
};



const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(metadata))});
await nftFileMetadataFile.saveIPFS();



const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
const nftFileMetadataFileHash = nftFileMetadataFile.hash();

const nftId = await mintNft(nftFileMetadataFilePath);



// Simple syntax to create a new subclass of Moralis.Object.
const Item = Moralis.Object.extend("Item");
// Create a new instance of that class.
const item = new Item();
item.set('name', createItemNameField.value);
item.set('description', createItemDescriptionField.value);
item.set('nftFilePath', nftFilePath);
item.set('nftFileHash', nftFileHash);
item.set('metadataFilePath', nftFileMetadataFilePath);
item.set('metadataFileHash', nftFileMetadataFileHash);
item.set('nftId', nftId);
item.set('nftContractAddress', TOKEN_CONTRACT_ADDRESS);

await item.save();
console.log(item);




user = await Moralis.User.current();
const userAddress = user.get("ethAddress");

switch(createItemStatusField.value){
    case "0":
        return;
    case "1":
        await ensureMarketplaceIsApproved(nftId, TOKEN_CONTRACT_ADDRESS);
        await marketplaceContract.methods.addItemToMarket(nftId, TOKEN_CONTRACT_ADDRESS, createItemPriceField.value).send({from: userAddress });
        break;
    case "2":
        alert("Not yet supported!");
        return;
}

}

mintNft = async (metadataUrl) => {
const receipt = await tokenContract.methods.createItem(metadataUrl).send({from: ethereum.selectedAddress});
console.log(receipt);
return receipt.events.Transfer.returnValues.tokenId;
}

openUserItems = async () => {
user = await Moralis.User.current();
if (user){
$(’#userItems’).modal(‘show’);
}else{
login();
}
}

loadUserItems = async () => {
const ownedItems = await Moralis.Cloud.run(“getUserItems”);
ownedItems.forEach(item => {
const userItemListing = document.getElementById(user-item-${item.tokenObjectId});
if (userItemListing) return;
getAndRenderItemData(item, renderUserItem);
});
}

loadItems = async () => {
const items = await Moralis.Cloud.run(“getItems”);
user = await Moralis.User.current();
items.forEach(item => {
if (user){
if (user.attributes.accounts.includes(item.ownerOf)){
const userItemListing = document.getElementById(user-item-${item.tokenObjectId});
if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
getAndRenderItemData(item, renderUserItem);
return;
}
}
getAndRenderItemData(item, renderItem);
});
}

initTemplate = (id) => {
const template = document.getElementById(id);
template.id = “”;
template.parentNode.removeChild(template);
return template;
}

renderUserItem = async (item) => {
const userItemListing = document.getElementById(user-item-${item.tokenObjectId});
if (userItemListing) return;

const userItem = userItemTemplate.cloneNode(true);
userItem.getElementsByTagName("img")[0].src = item.image;
userItem.getElementsByTagName("img")[0].alt = item.name;
userItem.getElementsByTagName("h5")[0].innerText = item.name;
userItem.getElementsByTagName("p")[0].innerText = item.description;

userItem.getElementsByTagName("input")[0].value = item.askingPrice ?? 1;
userItem.getElementsByTagName("input")[0].disabled = item.askingPrice > 0;
userItem.getElementsByTagName("button")[0].disabled = item.askingPrice > 0;
userItem.getElementsByTagName("button")[0].onclick = async () => {
    user = await Moralis.User.current();
    if (!user){
        login();
        return;
    }
    await ensureMarketplaceIsApproved(item.tokenId, item.tokenAddress);
    await marketplaceContract.methods.addItemToMarket(item.tokenId, item.tokenAddress, userItem.getElementsByTagName("input")[0].value).send({from: user.get('ethAddress') });
};

userItem.id = `user-item-${item.tokenObjectId}`
userItems.appendChild(userItem);

}

renderItem = (item) => {
const itemForSale = marketplaceItemTemplate.cloneNode(true);
if (item.sellerAvatar){
itemForSale.getElementsByTagName(“img”)[0].src = item.sellerAvatar.url();
itemForSale.getElementsByTagName(“img”)[0].alt = item.sellerUsername;
}

itemForSale.getElementsByTagName("img")[1].src = item.image;
itemForSale.getElementsByTagName("img")[1].alt = item.name;
itemForSale.getElementsByTagName("h5")[0].innerText = item.name;
itemForSale.getElementsByTagName("p")[0].innerText = item.description;

itemForSale.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
itemForSale.getElementsByTagName("button")[0].onclick = () => buyItem(item);
itemForSale.id = `item-${item.uid}`;
itemsForSale.appendChild(itemForSale);

}

getAndRenderItemData = (item, renderFunction) => {

fetch(item.tokenUri)
.then(response => response.json())
.then(data => {
    item.name = data.name;
    item.description = data.description;
    item.image = data.image;
    renderFunction(item);
})

}

ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {
user = await Moralis.User.current();
const userAddress = user.get(‘ethAddress’);
const contract = new web3.eth.Contract(tokenContractAbi, tokenAddress);
const approvedAddress = await contract.methods.getApproved(tokenId).call({from: userAddress});
if (approvedAddress != MARKETPLACE_CONTRACT_ADDRESS){
await contract.methods.approve(MARKETPLACE_CONTRACT_ADDRESS,tokenId).send({from: userAddress});
}
}

buyItem = async (item) => {
user = await Moralis.User.current();
if (!user){
login();
return;
}
await marketplaceContract.methods.buyItem(item.uid).send({from: user.get(‘ethAddress’), value: item.askingPrice});
}

hideElement = (element) => element.style.display = “none”;
showElement = (element) => element.style.display = “block”;

// Navbar
const userConnectButton = document.getElementById(“btnConnect”);
userConnectButton.onclick = login;

const userProfileButton = document.getElementById(“btnUserInfo”);
userProfileButton.onclick = openUserInfo;

const openCreateItemButton = document.getElementById(“btnOpenCreateItem”);
openCreateItemButton.onclick = () => $(’#createItem’).modal(‘show’);

// User profile
const userInfo = document.getElementById(“userInfo”);
const userUsernameField = document.getElementById(“txtUsername”);
const userEmailField = document.getElementById(“txtEmail”);
const userAvatarImg = document.getElementById(“imgAvatar”);
const userAvatarFile = document.getElementById(“fileAvatar”);

document.getElementById(“btnCloseUserInfo”).onclick = () => hideElement(userInfo);
document.getElementById(“btnLogout”).onclick = logout;
document.getElementById(“btnSaveUserInfo”).onclick = saveUserInfo;

// Item creation
const createItemForm = document.getElementById(“createItem”);

const createItemNameField = document.getElementById(“txtCreateItemName”);
const createItemDescriptionField = document.getElementById(“txtCreateItemDescription”);
const createItemPriceField = document.getElementById(“numCreateItemPrice”);
const createItemStatusField = document.getElementById(“selectCreateItemStatus”);
const createItemFile = document.getElementById(“fileCreateItemFile”);
document.getElementById(“btnCloseCreateItem”).onclick = () => hideElement(createItemForm);
document.getElementById(“btnCreateItem”).onclick = createItem;

// User items
const userItemsSection = document.getElementById(“userItems”);
const userItems = document.getElementById(“userItemsList”);
document.getElementById(“btnCloseUserItems”).onclick = () => hideElement(userItemsSection);
const openUserItemsButton = document.getElementById(“btnMyItems”);
openUserItemsButton.onclick = openUserItems;

const userItemTemplate = initTemplate(“itemTemplate”);
const marketplaceItemTemplate = initTemplate(“marketplaceItemTemplate”);

// Items for sale
const itemsForSale = document.getElementById(“itemsForSale”);

init();

//…
//and here is code for index.html

//index.html

NFT MarketPlace NFT Market Place
Profile
  • Explore
  • About
  • Create Connect wallet
        </div>
        </div>
      </nav>
    
    <!--Modal for MarketPlace Items-->
    <div class="container">
        <div class="row row-cols-1 row-cols-md-4 mt-5" id="itemsForSale">
    
        </div>
    </div>
    
    <div class="col mb-4" id="marketplaceItemTemplate">
        <div class="card h-100 border-light bg-transparent text-light">
            <nav class="card-header navbar navbar-dark text-light p-1">
                <img src="" alt="" width="30" height="30">
                <span></span>
            </nav>
         
            <img src="..." class="card-img-top" alt="...">
            <div class="card-body d-flex align-items-end">
                <div class="w-100">
                    <h5 class="card-title"></h5>
                    <p class="card-text"></p>
                    <button class="btn btn-primary btn-block"></button>
                </div>
        
            </div>
          </div>
    </div>
    
    <!-- Modal for userinfo -->
    <div class="modal fade" id="userInfo" tabindex="-1">
        <div class="modal-dialog">
        <div class="modal-content bg-dark text-light">
            <div class="modal-header">
            <h5 class="modal-title" >User Profile</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            </div>
            <div class="modal-body">
    
                <div class="form-group">
                    <label for="txtUsername">Username</label>
                    <input type="text" class="form-control" id="txtUsername" required placeholder="Enter username">
                </div>
    
                <div class="form-group">
                    <label for="txtEmail">Email address</label>
                    <input type="email" class="form-control" id="txtEmail" aria-describedby="emailHelp" placeholder="Enter email">
                    <small id="emailHelp" class="form-text text-muted">Optional</small>
                </div>
        
                <img width="50" height="50" src="" id="imgAvatar" alt="">
    
                <div class="form-group">
                    <label for="fileAvatar">Select Profile Pic</label>
                    <input type="file" class="form-control-file" id="fileAvatar">
                </div>
            </div>
            <div class="modal-footer">
            <button type="button" id="btnLogout" class="btn btn-secondary" data-dismiss="modal">Log out</button>
            <button type="button" id="btnCloseUserInfo" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <button type="button" id="btnSaveUserInfo" class="btn btn-primary">Save</button>
            </div>
        </div>
        </div>
    </div>
    
    Create Item
    ×
            <div class="form-group">
                <label for="txtUsername">Name</label>
                <input type="text" class="form-control" id="txtCreateItemName" required placeholder="Enter name">
            </div>
    
            <div class="form-group">
                <label for="txtCreateItemDescription">Description</label>
                <textarea class="form-control" id="txtCreateItemDescription"  cols="30" rows="5" placeholder="Enter description"></textarea>
            </div>
            <div class="form-group">
                <label for="txtUsername">Price</label>
                <input type="number" min="1" step="1" id="numCreateItemPrice" placeholder="Enter price" required class="form-control">
            </div>
    
            <div class="form-group">
                <label for="selectCreateItemStatus">Status</label>
                <select class="form-control" id="selectCreateItemStatus">        
                    <option value="0">Not for sale</option>
                    <option value="1">Instant buy</option>
                    <option value="2">Accept Offers</option>
                </select>
            </div>
    
            <div class="form-group">
                <label for="fileCreateItemFile">Select file</label>
                <input type="file" class="form-control-file" id="fileCreateItemFile">
            </div>
        </div>
        <div class="modal-footer">
        <button type="button" id="btnCloseCreateItem" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" id="btnCreateItem" class="btn btn-primary">Create!</button>
        </div>
    </div>
    </div>
    
    My Items
    ×
        </div>
        <div class="modal-footer">
            <button type="button" id="btnCloseUserItems" class="btn btn-secondary" data-dismiss="modal">Close</button>
        </div>
    </div>
    </div>
    
    ...
                <div class="input-group mb-3">
                    <input type="number" min="1" step="1" class="form-control" placeholder="Price">
                    <div class="input-group-append">
                      <button class="btn btn-outline-secondary" type="button">Put for sale</button>
                    </div>
                  </div>
            </div>
    
        </div>
      </div>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
    
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>
    <script src="abi.js"></script>
    <script src="main.js"></script>
    

    try to use Moralis SDK version 0.0.184 if you don’t know how to fix it in the latest version of Moralis SDK

    Fix the following things before that

    1. use the latest script for Moralis unpkg
      <script src="https://unpkg.com/moralis@latest/dist/moralis.js"></script>

    2. Update how server is initialized.
      Moralis.start({ serverUrl, appId });

    Let us know if you see any errors after this.

    Thank you very much !! This platform is really very helpful.
    Following @johnversus and @cryptokid 's instructions solved my problem.
    I have changed the script to verison 0.0.184 by:
    script src=“https://unpkg.com/[email protected]/dist/moralis.js”>
    and then executed
    npm install [email protected]

    Now it is working fine
    Thanks.

    1 Like

    I can now successfully upload items but the “PUT FOR SALE” option from my items is not working… it is not clickable now… When i upload items they go to my items now to put for sale in marketplace … the option is not working

    can you share the app link, if it is deployed somewhere

    No, I am running it on local host in my pc… If you have any place to deploy the app please let me know… or I can upload the whole code in google drive so that you can check it.

    @johnversus @cryptokid Help please

    you can deploy it on your moralis server: https://docs.moralis.io/moralis-dapp/tools/hosting

    you can also look in your browser console to see if there are any errors

    I have tried and now put for sale option is clickable but it is showing this error in meta mask

    and when I click on I will try in anyway and confirm the transaction, it shows this error:

    Check if the NFT that you are trying to sell is owned by the same wallet in which you are making a transaction.

    and the error in the console also says it is already listed on sale.

    SOLVED , It was because of the same account !! Thanks @johnversus

    2 Likes