'How can I connect IPFS with infura when uploading data?
I'm creating an NFT marketplace using hardhat, solidity & Next js, I have a form from where I enter some specific information about the NFT, then by clicking on the button "Create Digital Asset" The function "createMarket" should run to create an NFT and list it on the marketplace. When I clicked on the button to run the function "createMarket", I run into an error in these 2 lines of code saying that data in undefined!
const url = `https://ipfs.infura.io/ipfs/${added.path}.
const data = JSON.stringify({
name, description, image: fileUrl
});
I don't know how to solve it, I've tried to debug but everything seems right
What do you think ?
Btw I'm following this tutorial: https://www.youtube.com/watch?v=GKJBEEXUha0&t=6399s.
This is my Create-items component:
import { useState } from 'react';
import { ethers } from 'ethers';
import { create as ipfsHttpClient } from "ipfs-http-client";
import { useRouter } from 'next/router';
import Web3Modal from 'web3modal'
const client = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0');
// import address
import {nftaddress, nftmarketaddress} from "../config";
console.log(nftaddress, nftmarketaddress);
// import JSon files
import NFT from "../artifacts/contracts/NFT.sol/NFT.json"
import Market from "../artifacts/contracts/Market.sol/NFTMarket.json";
export default function CreateItems() {
const [fileUrl, setFileUrl] = useState(null);
console.log(fileUrl);
const [formInput, updateFormInput] = useState({ price: '', name: '', description: '' });
console.log(formInput);
// create a reference to useRouter
const router = useRouter();
/* function to create and update the URL file */
async function onChange(e) {
const file = e.target.files[0]
console.log(file)
try {
const added = await client.add(
file,
{
progress: (prog) => console.log(`received: ${prog}`)
}
)
***const url = `https://ipfs.infura.io/ipfs/${added.path}`***
setFileUrl(url)
} catch (error) {
console.log('Error uploading file: ', error)
}
}
/* Function to create an items and save it to IPFS*/
async function createMarket() {
const { name, description, price } = formInput;
if(!name || !description ||!price || fileUrl) return
// Js object to data
const data = JSON.stringify({
name, description, image: fileUrl
});
console.log(data);
try {
const added = await client.add(data)
const url = `https://ipfs.infura.io/ipfs/${added.path}`
/* after file is uploaded to IPFS, pass the URL to save it on Polygon */
createSale(url)
} catch (error) {
console.log('Error uploading file: ', error)
}
}
/*Function for listing Items for sale */
async function createSale(url) {
const web3Modal = new Web3Modal()
console.log(web3Modal);
const connection = await web3Modal.connect()
const provider = new ethers.providers.Web3Provider(connection)
const signer = provider.getSigner()
/* create or mint the NFT */
let contract = new ethers.Contract(nftaddress, NFT.abi, signer)
let transaction = await contract.createToken(url)
let tx = await transaction.wait()
let event = tx.events[0]
let value = event.args[2]
let tokenId = value.toNumber()
// parse what amount of ether that the user will enter in the input to Wei
const price = ethers.utils.parseUnits(formInput.price, 'ether');
/* List the items on sale on the marketplace */
contract = new ethers.Contract(nftmarketaddress, Market.abi, signer)
let listingPrice = await contract.getListingPrice()
listingPrice = listingPrice.toString()
transaction = await contract.createMarketItem(nftaddress, tokenId, price, {value: listingPrice});
await transaction.wait();
// push the user to the Home page
router.push("/")
}
return (
<div className="flex justify-center">
<div className="w-1/2 flex flex-col pb-12">
<input
placeholder="Asset Name"
className="mt-8 border rounded p-4"
onChange={(e)=> updateFormInput({...formInput, name: e.target.value})}
/>
<textarea
placeholder="Asset Description"
className="mt-2 border rounded p-4"
onChange={(e)=> updateFormInput({...formInput, description: e.target.value})}
/>
<input
placeholder="Asset Price in Eth"
className="mt-2 border rounded p-4"
onChange={(e)=> updateFormInput({...formInput, price: e.target.value})}
/>
<input
type="file"
name="asset"
className='my-4'
onChange={onChange}
/>
{
fileUrl && (
<img className='rounded mt-4' width="350" src={fileUrl}/>
)
}
<button onClick={createMarket} className="font-bold mt-4 bg-pink-500 text-white rounded p-4 shadow-lg">
Create Digital Asset
</button>
</div>
</div>
)
}
Solution 1:[1]
there is a bug here:
if(!name || !description ||!price || fileUrl) return
it should be !fileUrl
.
Looks like you ipfs api requires all of those defined. that is why author makes sure all of those are defined.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Yilmaz |