Value not being displayed after render

I have been fetching pool data from the constants file. I have been assigned to create a featured vault i.e. the vault having highest APY Reward value after fetching from the API. I fetched all the three from the API and did my calculations. I am getting the value printed on the console but it does not appear in the component itself.

export const FeaturedPool = () => {
  // @ts-ignore
  const [loading, setLoading] = useState(true);
  // @ts-ignore
  let poolsArray = {};
  let poolDetails: PoolInfo | undefined;

  useEffect(() => {
    let counter = 0;
    POOLS?.filter((x) => x.stableCoins)?.map((pool) => {
      // fetchAPYData(pool.targetedAPYId);
      // @ts-ignore
      poolsArray[pool.targetedAPYId] = "";
      fetch("https://yields.llama.fi/chart/" + pool.targetedAPYId)
        .then((response) => {
          return response.json();
        })
        .then((res) => {
          let result = res.data.at(-1).apyReward.toFixed(2);
          // @ts-ignore
          poolsArray[pool.targetedAPYId] = result;
          counter++;
          if (counter == 3) {
            console.log("ALL 3 FETCHED");
            let arr = Object.values(poolsArray);

            // @ts-ignore
            let max = Math.max(...arr);
            const poolKey =
              // @ts-ignore
              Object.keys(poolsArray).find((key) => poolsArray[key] == max);
            // ts-ignore
            poolDetails = POOLS.find((x) => x.targetedAPYId == poolKey);

            console.log(poolDetails);
            console.log(poolDetails?.title);
            setLoading(false);
          }
        });
    });
  }, []);

 return (
   This line is causing problem. Title does not appear 
<>{loading ? <p>Loading... </p> : <p>Loaded {poolDetails?.title}</p>}</>
  );
};
export type PoolInfo = {
  id: string;
  title: string;
  description: string;
  icon: string;
  score: number;
  risk: string;
  apyRange: string;
  targetedAPYId?: string;
  targetedAPY: string;
  tvlId?: string;
  strategy: string;
  vaultAddress: string;
  strategyAddress: string;
  zapAddress: string;
  isRetired?: boolean;
  stableCoins?: boolean;
  wantToken: string;
  isOld?: boolean;
  details?: string;
  benefits?: string[];
  promptTokens?: Token[];
};

I want the display the vault having highest apy reward value

>Solution :

There are a few issues in your code that could be causing the problem. Let’s go through them and make the necessary corrections:

  1. Incorrectly defined poolsArray as an object instead of an array:

    // Incorrect
    let poolsArray = {};

    // Correct
    let poolsArray = [];

  2. Improperly assigning values to poolsArray:

    // @ts-ignore
    poolsArray[pool.targetedAPYId] = "";

  3. Since poolsArray is now an array, you should use the push method to
    add values to it:

    poolsArray.push({ targetedAPYId: pool.targetedAPYId, apyReward: "" });

  4. Updating poolsArray with the fetched values:

    // @ts-ignore
    poolsArray[pool.targetedAPYId] = result;

  5. Instead of assigning the value directly, you should update the
    corresponding object in the poolsArray array:

    poolsArray.forEach((poolItem) => {
    if (poolItem.targetedAPYId === pool.targetedAPYId) {
    poolItem.apyReward = result;
    }
    });

  6. Comparing counter with the number 3 using the strict equality
    operator:

    if (counter == 3) {

    Use the strict equality operator (===) to compare counter with the number 3:

    if (counter === 3) {

  7. Incorrect usage of ts-ignore comments:

    // ts-ignore
    poolDetails = POOLS.find((x) => x.targetedAPYId == poolKey);

  8. The correct comment should be @ts-ignore:

    // @ts-ignore
    poolDetails = POOLS.find((x) => x.targetedAPYId === poolKey);

  9. Incorrectly accessing the poolDetails in the JSX code:

    <>{loading ?

    Loading…

    :

    Loaded {poolDetails?.title}

    }</>

    You should assign the poolDetails value to a state variable so that the component can rerender when it changes. Replace the poolDetails variable with a state variable and update it accordingly:

    const [featuredPool, setFeaturedPool] = useState<PoolInfo | undefined>(undefined);

    // Inside the useEffect callback:
    setFeaturedPool(POOLS.find((x) => x.targetedAPYId === poolKey));

    // In the JSX code:
    <>{loading ?

    Loading…

    :

    Loaded {featuredPool?.title}

    }</>

  10. With these corrections, your code should work as expected and
    display the title of the vault with the highest APY reward value.

import React, { useEffect, useState } from 'react';

export const FeaturedPool = () => {
  const [loading, setLoading] = useState(true);
  const [featuredPool, setFeaturedPool] = useState<PoolInfo | undefined>(undefined);

  useEffect(() => {
    let counter = 0;
    let poolsArray: PoolData[] = [];

    POOLS?.filter((x) => x.stableCoins)?.forEach((pool) => {
      poolsArray.push({ targetedAPYId: pool.targetedAPYId, apyReward: "" });

      fetch("https://yields.llama.fi/chart/" + pool.targetedAPYId)
        .then((response) => response.json())
        .then((res) => {
          const result = res.data.at(-1).apyReward.toFixed(2);
          poolsArray.forEach((poolItem) => {
            if (poolItem.targetedAPYId === pool.targetedAPYId) {
              poolItem.apyReward = result;
            }
          });

          counter++;
          if (counter === 3) {
            const arr = poolsArray.map((poolItem) => poolItem.apyReward);
            const max = Math.max(...arr);
            const poolKey = poolsArray.find((poolItem) => poolItem.apyReward === max)?.targetedAPYId;

            if (poolKey) {
              const foundPool = POOLS.find((pool) => pool.targetedAPYId === poolKey);
              setFeaturedPool(foundPool);
            }

            setLoading(false);
          }
        });
    });
  }, []);

  return (
    <>
      {loading ? <p>Loading...</p> : <p>Loaded {featuredPool?.title}</p>}
    </>
  );
};

export type PoolData = {
  targetedAPYId: string;
  apyReward: string;
};

export type PoolInfo = {
  id: string;
  title: string;
  description: string;
  icon: string;
  score: number;
  risk: string;
  apyRange: string;
  targetedAPYId?: string;
  targetedAPY: string;
  tvlId?: string;
  strategy: string;
  vaultAddress: string;
  strategyAddress: string;
  zapAddress: string;
  isRetired?: boolean;
  stableCoins?: boolean;
  wantToken: string;
  isOld?: boolean;
  details?: string;
  benefits?: string[];
  promptTokens?: Token[];
};
  1. Make sure to replace PoolInfo and PoolData types with their actual
    definitions if they are imported from other files. Also, ensure
    that the POOLS variable is properly imported or defined in your
    code.

Leave a Reply