如何修复Moralis API获取的Token元数据中metadata字段JSON格式异常问题
Problem Description
I wrote code to fetch data from an API and save it to a file: using Moralis.Web3API.token.getTokenIdMetadata to retrieve token metadata. Since the returned object has a lot of unnecessary information, I extract the required fields into a new tokenMetadata object and save it to a file. Here's the code:
const tokenIdMetadata = await Moralis.Web3API.token.getTokenIdMetadata(options); const tokenMetadata = {}; tokenMetadata.token_id = tokenIdMetadata.token_id; tokenMetadata.metadata = tokenIdMetadata.metadata; fs.writeFileSync(folderName.concat('/', collectionSlug, '_', tokenID, '.json'), JSON.stringify(tokenMetadata, null, 4));
The issue is that the metadata field in the generated JSON file is stored as an escaped string, which doesn't match the expected format:
"token_id": "4", "metadata": "{\"name\":\"Arcade Land Mega #4\",\"image\":\"ipfs://QmaJyxmwWkH17P7cpzRDFqcQwh7HYZ53VS9pJN3rtWKVPh\",\"description\":\"Arcade Lands are digital properties in an interoperable metaverse that serves as your web3 home for all your NFTs. Land owners will get additional benefits within the Arcadeverse.\",\"attributes\":[{\"trait_type\":\"Size\",\"value\":\"Mega\"},{\"trait_type\":\"Area\",\"value\":\"Frozen\"},{\"trait_type\":\"Underground\",\"value\":\"Weird Rocks\"}]}"
The expected format should have metadata as a nested JSON object:
"token_id" : "4", "metadata" : { "name": "Arcade Land Mega #4", "image": "ipfs://QmXYYbVEFqVPRELzPN3fgCw9v3wr2iQqixbVaGS1JTH6mS", "description": "Arcade Lands are digital properties in an interoperable metaverse that serves as your web3 home for all your NFTs. Land owners will get additional benefits within the Arcadeverse.", "attributes": [ { "trait_type": "Size", "value": "Mega" }, { "trait_type": "Area", "value": "Frozen" }, { "trait_type": "Underground", "value": "Weird Rocks" } ] }
How can I modify the code to fix this formatting issue?
Solution
The core problem here is that the metadata value returned by the Moralis API is a JSON-encoded string, not a native JavaScript object. When you pass this string directly to JSON.stringify(), it gets escaped instead of being serialized as a nested object.
To fix this, you need to parse the string into a JavaScript object using JSON.parse() before assigning it to tokenMetadata.metadata. Here's the updated code:
const tokenIdMetadata = await Moralis.Web3API.token.getTokenIdMetadata(options); const tokenMetadata = {}; tokenMetadata.token_id = tokenIdMetadata.token_id; // Parse the JSON string into an object tokenMetadata.metadata = JSON.parse(tokenIdMetadata.metadata); fs.writeFileSync(`${folderName}/${collectionSlug}_${tokenID}.json`, JSON.stringify(tokenMetadata, null, 4));
Important Note: Handle Potential Parsing Errors
Sometimes, NFT metadata strings might be malformed or invalid JSON. To avoid your code crashing when this happens, wrap the parsing step in a try-catch block:
const tokenIdMetadata = await Moralis.Web3API.token.getTokenIdMetadata(options); const tokenMetadata = {}; tokenMetadata.token_id = tokenIdMetadata.token_id; try { tokenMetadata.metadata = JSON.parse(tokenIdMetadata.metadata); } catch (error) { console.error(`Failed to parse metadata for token ID ${tokenID}:`, error); // Optionally fall back to the original string or skip saving this token tokenMetadata.metadata = tokenIdMetadata.metadata; } fs.writeFileSync(`${folderName}/${collectionSlug}_${tokenID}.json`, JSON.stringify(tokenMetadata, null, 4));
This way, even if the metadata is invalid, your code will continue to run and you'll get a clear error message to debug.
内容的提问来源于stack exchange,提问作者Ben

