How can exceptions be resolved defined btoa

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

The following exception message is displayed:

Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

Using buffer
const btoa = function(str){ return Buffer.from(str).toString('base64'); }
will prompt you again:

Buffer is not defined

Does anyone know how to solve this problem?

it looks like your buffer has some characters that may be binary, and they can not be converted to string

what is that metadata buffer that gives you that error?

This is all of my code

<html>

<head>
  <!-- Moralis SDK code -->
  <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
  <script src="https://unpkg.com/moralis/dist/moralis.js"></script>
</head>

<body>
  <input type="file" id="profilePhotoFileUpload"><br />
  name:<input type="text" id="name"><br />
  description:<input type="text" id="description"><br />
  <button id="newIPFS">New IPFS</button><br />
</body>
<script>
  // connect to Moralis server
  const serverUrl = "https://...";
  const appId = "...";

  const fileUploadControl = document.getElementById("profilePhotoFileUpload");
  const itemName = document.getElementById("name");
  const itemDescription = document.getElementById("description");

  //初始化
  Moralis.start({ serverUrl, appId });

  // const btoa = function(str){ return Buffer.from(str).toString('base64'); }

  createNFTItem = async () => {

    if (fileUploadControl.files.length <= 0) {
      alert("Please slect a file !");
      return;
    }
    const file = fileUploadControl.files[0];
    const name = "profile_picture.png";

    const nftFile = new Moralis.File(name, file);
    await nftFile.saveIPFS()
    const nftHash = nftFile.hash();
    const nftPath = nftFile.ipfs();
    console.log("nftPath:" + nftPath);
    const metadata = {
      name: itemName.value,
      description: itemDescription.value,
      nftFilePath: nftPath,
      nftFileHash: nftHash
    };

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

    const nftMetadataPath = nftMetadataFile.ipfs();
    const nftMetadataHash = nftMetadataFile.hash();
    console.log("nftMetadataPath:" + nftMetadataPath);

    const NFTItem = Moralis.Object.extend("NFTItem");
    const nftItem = new NFTItem();
    nftItem.set('name', itemName.value);
    nftItem.set('description', itemDescription.value);
    nftItem.set('nftFilePath', nftPath);
    nftItem.set('nftFileHash', nftHash);
    nftItem.set('nftMetadataPath', nftMetadataPath);
    nftItem.set('nftMetadataHash', nftMetadataHash);
    await nftItem.save();

    console.log("nftItem:" + nftItem);
  }

  document.getElementById("newIPFS").onclick = createNFTItem;
</script>

</html>

I know how to solve this problem, I should write it like this:

    var metadataBase64Str = btoa(unescape(encodeURIComponent(JSON.stringify(metadata))));
    console.info("metadata base64:",metadataBase64Str);

    const nftMetadataFile = new Moralis.File("metadata.json", { base64: metadataBase64Str });

stackoverflow reference

2 Likes

Nice work @milk3688 ! Thank you for sharing the solution :man_mechanic: