0

I am new to the SQL scene and I am trying to use Supabase for a web app that I am building. I am trying to push an array objects to the DB, but what I am finding is that it only grabs the first element in the array and adds that to the DB. The end goal functionality is that it grabs the whole array of objects and pushes that and if it detects a change (why I am using upsert) then add that object to the array.

ownedNFTs is an array of objects.

 const nakedDB =  () => {
        try {
          setLoading(true);
          ownedNFTs.forEach(async (nft) => {
              
            let { data, error, status } = await supabase.from("Users").upsert({
              wallet_address: wallet?.accounts[0].address,
              NFTS: {
                name: nft?.metadata?.name || "",
                description: nft?.metadata?.description || "",
                image: nft?.metadata?.image || "",
                externalUrl: nft?.metadata?.external_url || "",
                contractAddress: nft?.contract.address || "",
                tokenId: nft?.id.tokenId || "",
                blockchain: "Ethereum",
                metaverse: nft?.metadata?.name.split(" ")[0] || "",
                metadata: nft?.metadata || "",
                symbol: nft?.contract.symbol || "",
              },
            }).eq('wallet_address', wallet?.accounts[0].address);
            console.log(data)
            if (error && status !== 406) {
              throw error;
            }
          });
       
        } catch (error) {
          console.table(error);
        } finally {
          setLoading(false);
        }
      };

I have tried following the Supabase documentation on bulkupserting, but that is to create multiple rows at once. I have also tried creating a standard for loop, but that didnt work as well. My current implementation is using forEach() and that is not working as expected.

AS11
  • 9
  • 5
  • What error do you get when running this? – Mansueli Nov 04 '22 at 13:55
  • @Mansueli I don’t get an error. It works fine. The problem is that there are two objects In the array and it only puts the first object into the DB. – AS11 Nov 04 '22 at 15:09
  • Have you tried to set them up in a [Promise](https://stackoverflow.com/a/37576787/2188186)? – Mansueli Nov 04 '22 at 19:12
  • @Mansueli I am using async await, but I can try promise.all(). I am just unclear how that would help. It seems to be an issue writing to the DB. Would be able to explain what your thought process is? – AS11 Nov 04 '22 at 19:37
  • @Mansueli I tried the promise.all() example that you gave and that did not work. Its still only saving the first element in the array – AS11 Nov 05 '22 at 01:33

1 Answers1

1

The problem why it was selecting the first element (I believe) is because the .foreach() function was not running multiple times. This was not a clean way to do a DB call in any case. In addition to that I do think that the data I was sending to the DB was not in the correct format as a pure array of objects. For example when you use .map() it returns two separate objects. Supabase (in my configuration) was not expecting this format. The solution is below.

  1. I created an empty array
  2. I used .map() on my array of objects
  3. Saved the result of the .map() to the array I created.
  4. Sent the new array to the DB in one call.

      const nakedDB = async () => {
        try {
          ownedNFTs.map((nft) => {
            // console.log(nft)
            nftArray.push(nft);
          });

          setLoading(true);
          let { data, error, status } = await supabase
            .from("Users")
            .upsert({
              wallet_address: wallet?.accounts[0].address,
              NFTS: nftArray,
            })
            .eq("wallet_address", wallet?.accounts[0].address);
          if (error && status !== 406) {
            throw error;
          }
        } catch (error) {
          console.table(error);
        } finally {
          setLoading(false);
        }
      };

** Updated Solution ** ownedNFTs is already an array of objects in the proper format. I removed the .map() and directly saved ownedNFTs to the DB and it saves all elements. The .map() solution was me over-engineering the issue.

AS11
  • 9
  • 5