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:
-
Incorrectly defined poolsArray as an object instead of an array:
// Incorrect
let poolsArray = {};// Correct
let poolsArray = []; -
Improperly assigning values to poolsArray:
// @ts-ignore
poolsArray[pool.targetedAPYId] = ""; -
Since poolsArray is now an array, you should use the push method to
add values to it:poolsArray.push({ targetedAPYId: pool.targetedAPYId, apyReward: "" });
-
Updating poolsArray with the fetched values:
// @ts-ignore
poolsArray[pool.targetedAPYId] = result; -
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;
}
}); -
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) {
-
Incorrect usage of ts-ignore comments:
// ts-ignore
poolDetails = POOLS.find((x) => x.targetedAPYId == poolKey); -
The correct comment should be @ts-ignore:
// @ts-ignore
poolDetails = POOLS.find((x) => x.targetedAPYId === poolKey); -
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}
}</>
-
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[];
};
- 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.