我从另一个开发人员那里获得了一个使用Polkadot.js的React项目,我很难理解如何实现以下目标:
我想要显示一个图像网格。图像URL的初始部分是在const中硬编码的。
当用户单击按钮时,将异步检查用户的帐户,以查看他们拥有什么NFT。但是,没有一个数组/对象是我所需要的,所以我必须使用硬编码的URL以及提供的数字创建一个数组,并在字符串的末尾添加图像文件扩展名。eg.imageURL + imageNumber + '.png'
单击时调用的异步函数如下所示:
const getNFT = async (address: string) => {
const wsProvider = new WsProvider(wsUrl);
const api = await ApiPromise.create({ provider: wsProvider });
// NOTE the apps UI specified these in mega units -> https://polkadot.js.org/docs/api-contract/start/contract.read
// @ts-ignore
const gasLimit = -1;
// Read from the contract via an RPC call
const value = 0; // only useful on isPayable messages -> https://polkadot.js.org/docs/api-contract/start/contract.read
// @ts-ignore
const contract = new ContractPromise(api, abi, contractAddress);
const {gasConsumed, result, output} = await contract.query['psp34::balanceOf'](address, {value: 0, gasLimit: -1}, address);
console.log(JSON.stringify(result.toHuman()));
if (result.isOk) {
// should output 123 as per our initial set (output here is an i32)
// @ts-ignore
setUserNFTCount(output.toHuman());
// @ts-ignore
console.log('Number of NFT you own:', output.toHuman());
// @ts-ignore
for (let i = 0; i <= output.toNumber() - 1; i++) {
console.log ("Getting NFT at index " + i);
const NFTIndexResult = await contract.query['psp34Enumerable::ownersTokenByIndex'](address, { value: 0, gasLimit: -1 }, address, i);
if (NFTIndexResult.result.isOk && NFTIndexResult.output != null) {
console.log(NFTIndexResult);
console.log(NFTIndexResult.output.toHuman())
// @ts-ignore
var pNumber = NFTIndexResult.output.toHuman().Ok.U64;
console.log('NFT number you own:' + pNumber);
var metadata = metadataUrl + pNumber + '.json';
var image = imageUrl + pNumber + '.png';
console.log('TODO, show image: ' + image);
let myImageArray = [];
myImageArray.push(image)
console.log('array = ' + myImageArray);
}
}
} else {
console.error('Error', result.asErr);
}
}当我检查我的控制台时,我可以看到要添加到图像变量中的数组中的各个图像。但是,我不知道如何将每个图像添加到一个数组中,然后可以使用该数组来呈现图像的网格。
编辑-作为进一步的上下文:当我做控制台日志时,我只看到每一行的每个单独的图像路径,而不是一个数组,甚至当我将控制台日志移动到循环之外时也是如此。( Www.omewebsite.com/Image2.png) Www.omewebsite.com/Image1.png或)
发布于 2022-07-31 21:55:56
将数组声明在之外,这样它就不会在每次迭代时声明一个新数组。
示例:
const myImageArray = []; // <-- declare prior to loop
// @ts-ignore
for (let i = 0; i <= output.toNumber() - 1; i++) {
console.log ("Getting NFT at index " + i);
const NFTIndexResult = await contract.
query['psp34Enumerable::ownersTokenByIndex'](
address,
{ value: 0, gasLimit: -1 },
address,
i,
);
if (NFTIndexResult.result.isOk && NFTIndexResult.output != null) {
console.log(NFTIndexResult);
console.log(NFTIndexResult.output.toHuman());
// @ts-ignore
var pNumber = NFTIndexResult.output.toHuman().Ok.U64;
console.log('NFT number you own:' + pNumber);
var metadata = metadataUrl + pNumber + '.json';
var image = imageUrl + pNumber + '.png';
console.log('TODO, show image: ' + image);
myImageArray.push(image); // <-- push all into same array
console.log('array = ' + myImageArray);
}
}在循环结束后,您可能会对myImageArray做一些事情。
使用承诺对象数组进行更新
您可能会发现使用一个承诺对象数组来收集获取的图像更容易。
示例:
const promises = Array.from({ length: output.toNumber()})
.map((_, i) => {
return contract.
query['psp34Enumerable::ownersTokenByIndex'](
address,
{ value: 0, gasLimit: -1 },
address,
i,
)
.then(NFTIndexResult => {
if (NFTIndexResult.result.isOk && NFTIndexResult.output != null) {
console.log(NFTIndexResult);
console.log(NFTIndexResult.output.toHuman());
// @ts-ignore
const pNumber = NFTIndexResult.output.toHuman().Ok.U64;
console.log('NFT number you own:' + pNumber);
const metadata = metadataUrl + pNumber + '.json';
const image = imageUrl + pNumber + '.png';
console.log('TODO, show image: ' + image);
return image;
}
});
});
const myImageArray = await Promise.all(promises);
console.log('array = ' + myImageArray);发布于 2022-07-31 22:04:27
看来你的问题是范围问题。我假设您希望在异步函数的外部拥有图像url数组:
const getNFT = async (address: string) => 我看到您在for循环中声明了一个局部变量myImageArray。这将引起一些问题。它至少需要在for循环之外,这样就不会使用新的空数组覆盖变量,从而擦除所有数据。
解决这个问题的方法有很多种,但最好的方法可能是收集结果,类似于当前的方法,然后从函数返回值。见下面的示例:
const myImageArray = []; // Declare your array here so if you fail to retrieve you are returning an empty array (if that is your desired behavior)
console.log(JSON.stringify(result.toHuman()));
if (result.isOk) {
// should output 123 as per our initial set (output here is an i32)
// @ts-ignore
setUserNFTCount(output.toHuman());
// @ts-ignore
console.log('Number of NFT you own:', output.toHuman());
// @ts-ignore
for (let i = 0; i <= output.toNumber() - 1; i++) {
console.log("Getting NFT at index " + i);
const NFTIndexResult = await contract.query['psp34Enumerable::ownersTokenByIndex'](address, { value: 0, gasLimit: -1 }, address, i);
if (NFTIndexResult.result.isOk && NFTIndexResult.output != null) {
// removed for brevity
var image = imageUrl + pNumber + '.png'
myImageArray.push(image);
}
}
} else {
console.error('Error', result.asErr);
}
return myImageArray; // return the array, as that is the data you seem to want out of the function然后您可以在其他地方使用您的函数,如下所示:
const imageArray = await getNFT('someAddress')https://stackoverflow.com/questions/73187160
复制相似问题