useMoralisCloudQuery:: data: null

I’m trying to follow this tutorial. I have all the code in place including updating it with fixes. youtube.com/watch?v=_2V4peyS0Ns&list=PL22031CpfcRcdcP2VY0qSYqzbwro9fMuc&index=6

I’m having an issue with loading data. The image shows the desired result when I press search.

This is my cloud function.

Moralis.Cloud.define("getTokenBalances", async (request) => {
  const { userAddress, pageSize, pageNum } = request.params;
  const offset = (pageNum - 1) * pageSize;

  // count results
  const query = new Moralis.Query("EthTokenBalance");
  const matchPipeline = {
    match: {
      address: userAddress,
      contract_type: "ERC20",
      balance: { $ne: "0" },
    },
  };
  const countPipeline = { ...matchPipeline, count: "count" };
  const countResult = await query.aggregate(countPipeline);

  // get page
  const pagePipeline = {
    ...matchPipeline,
    addFields: {
      adjBal: {
        $divide: [
          { $toDouble: "$balance" },
          { $pow: [10, { $toDouble: "$decimals" }] },
        ],
      },
    },
    sort: { adjBal: -1 },
    skip: offset,
    limit: pageSize,
  };
  const pageResults = await query.aggregate(pagePipeline);

  const output = {
    results: pageResults,
    count: countResult[0].count,
  };

  return output;
});

Moralis.Cloud.define("searchEthAddress", async function (request) {
  const { address } = request.params;
  if (!address) {
    return null;
  }

  // find out if address is already watched
  const query = new Moralis.Query("WatchedEthAddress");
  query.equalTo("address", address);
  const watchCount = await query.count();

  if (watchCount > 0) {
    // already watched don't sync again
    return null;
  }

  // return Moralis.Cloud.run("watchEthAddress", { address });
  return Moralis.Cloud.run("watchEthAddress", { address }, { useMasterKey: true });
});

Moralis.Cloud.define("getTransactions", function (request) {
  const { userAddress, pageSize, pageNum } = request.params;
  const offset = (pageNum - 1) * pageSize;

  const query = new Moralis.Query("EthTransactions");
  query.equalTo("from_address", userAddress);
  query.descending("block_number");
  query.withCount();
  query.skip(offset);
  query.limit(pageSize);

  return query.find();
});

Moralis.Cloud.define("getTokenTranfers", async (request) => {
  const { userAddress, pageSize, pageNum } = request.params;
  const offset = (pageNum - 1) * pageSize;
  const output = {
    results: [],
    count: 0,
  };

  // count results
  const matchPipeline = {
    match: {
      $expr: {
        $or: [
          { $eq: ["$from_address", userAddress] },
          { $eq: ["$to_address", userAddress] },
        ],
      },
    },
    sort: { block_number: -1 },
    count: "count",
  };
  const query = new Moralis.Query("EthTokenTransfers");
  const countResult = await query.aggregate(matchPipeline);
  output.count = countResult[0].count;

  // get page results
  const lookupPipeline = {
    ...matchPipeline,
    skip: offset,
    limit: pageSize,
    lookup: {
      from: "EthTokenBalance",
      let: { tokenAddress: "$token_address", userAddress },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$token_address", "$$tokenAddress"] },
                { $eq: ["$address", "$$userAddress"] },
              ],
            },
          },
        },
      ],
      as: "EthTokenBalance",
    },
    unwind: "$EthTokenBalance",
  };
  delete lookupPipeline.count;

  output.results = await query.aggregate(lookupPipeline);
  return output;
});

Moralis.Cloud.define("getTokenBalances", async (request) => {
  const { userAddress, pageSize, pageNum } = request.params;
  const offset = (pageNum - 1) * pageSize;

  // count results
  const query = new Moralis.Query("EthTokenBalance");
  const matchPipeline = {
    match: {
      address: userAddress,
      contract_type: "ERC20",
      balance: { $ne: "0" },
    },
  };
  const countPipeline = { ...matchPipeline, count: "count" };
  const countResult = await query.aggregate(countPipeline);

  // get page
  const pagePipeline = {
    ...matchPipeline,
    addFields: {
      adjBal: {
        $divide: [
          { $toDouble: "$balance" },
          { $pow: [10, { $toDouble: "$decimals" }] },
        ],
      },
    },
    sort: { adjBal: -1 },
    skip: offset,
    limit: pageSize,
  };
  const pageResults = await query.aggregate(pagePipeline);

  const output = {
    results: pageResults,
    count: countResult[0].count,
  };

  return output;
});

And this is my cloudQuery.js code

import Moralis from "moralis";
import { useEffect, useState } from "react";

const defaultCloudQueryOptions = {
  includesCount: false,
  countName: "count",
  params: {},
  postProcess: (r) => r.attributes,
  onSuccess: () => {},
};

export function useMoralisCloudQuery(
  methodName,
  options = defaultCloudQueryOptions
) {
  const [state, setState] = useState({
    data: null,
    error: null,
    loading: false,
  });

  useEffect(() => {
    if (methodName) {
      setState((v) => ({ ...v, loading: true }));
      console.log("useMoralisCloudQuery:: methodName:", methodName," options:", options);
      Moralis.Cloud.run(methodName, options.params)
        .then((data) => {
          console.log("useMoralisCloudQuery:: data:", data);
          if (data) {
            let output = {};
            if (options.includesCount) {
              output.results = options.postProcess
                ? data.results.map(options.postProcess)
                : data.results;
              output[options.countName] = data[options.countName];
            } else {
              output = options.postProcess
                ? data.map(options.postProcess)
                : data;
            }
            console.log("useMoralisCloudQuery:: output:", output);

            setState({ data: output, error: null, loading: false });
          } else {
            setState({ data: null, error: null, loading: false });
          }

          if (typeof options.onSuccess === "function") {
            options.onSuccess();
          }
        })
        .catch((error) => {
          console.error(error);
          setState({ data: null, error, loading: false });
        });
    }
  }, [methodName, options]);

  return state;
}

What is your issue, are you not getting data from the cloud function? Or do you want to display it like the screenshot where the data renders differently based on the search value?

I want to display it like it’s shown in the screenshot.

You can post your component code, there is not enough to go on. Where is that screenshot from? If it’s from the tutorial, it should cover how to do it.

Yes, the screenshot is from the tutorial, and it should cover how to do it, I followed every step, however, it’s over a year old so I believe that is part of why I’m facing issues.
This is the link to the code I’m trying to use.

A reason you might not get it working is due to xxxTokenBalance classes were removed from the database.
You can look into this thread