I am struggling to parse data from my api result. I need to return a number from my getDailyRate function below. My code -
export type DailyRateType = {
'success': boolean;
'user' : string;
'quotes' : object;
}
export const getDailyRate = (day:string):number =>
{
let data = fetchDailyRates()
let quotes = data.quotes; //Gives error that 'quotes' doesnt exist in Promise<DailyRateType[]>
let quotes = data['quotes']; //Gives error similar to above
console.log(data); // prints out promise
}
const fetchDailyRates = async (): Promise<DailyRateType[]> =>
await (await fetch('http://myapilayer.net?format=1')).json();
However, if I test using a fake data by creating another function like this below, it works fine. However, I need to get it working with API data.
cons fetchDailyRates_v2 = (): DailyRateType[] => {
return [
{
success: true,
user: 'Admin',
quotes: {
'day1': 5.5,
'day2': 5.8,
'day3': 5.4,
}
}
];
}
UPDATE
As per suggestions below, I added asyc/await to getDailyRate:
export const getDailyRate = async (day:string) =>
{
let data = await fetchDailyRates();
let quotes = data['quotes'];
//Gives error - Element implicitly has an 'any' type because index expression is not of type 'number'.
console.log(data); // prints out promise
return 1;
}
Issues with this update -
Adding async/await creates another issue and asks me to remove 'number' type from the function as it becomes a Promise
The return type becomes Promise - I need it to be number only. So, if I just return number value (1 or 2). The return type becomes Promise and I try to assing this value to another place ... get this error "Type 'Promise' is not assignable to type 'number'."
CodePudding user response:
You can not use from result of an asynchronous function like as synchronous function, in the other hand when have Promise your desired type must be return by Promise (or don't specify type and it's consider any). I will show below with another way by custom hooks maybe useful for you:
//import required packages
export type DailyRateType = {
success: boolean;
user: string;
quotes: object;
};
export const useLazyQuery = () => {
const [loading, setLoading] = React.useState<boolean>(false);
const [data, setData] = React.useState([] as DailyRateType[]);
const _request = async = () => {
try {
setLoading(true);
const reponsedJson = await (await fetch('http://myapilayer.net?format=1')).json();
console.log(data); //optional
setData(reponsedJson);
setLoading(false);
} catch (error) {
console.error(error);
setLoading(false);
}
}
return [_request, {loading, data}];
}
And according to your response schema (fetchDailyRates_v2) for example in order to accessing to quotes in first element, you should use like data?.[0]?.quotes from that.
CodePudding user response:
You should use async/await for getDailyRate
,Check this:
export type DailyRateType = {
success: boolean;
user: string;
quotes: object;
};
async function getDailyRate(day: string): number {
let data = await fetchDailyRates();
let quotes = data?.['quotes'];
console.log(data, quotes);
return 1
}
const fetchDailyRates = async (): Promise<DailyRateType[]> =>
await (await fetch('http://myapilayer.net?format=1')).json();
at the and you need to call getDailyRate
like below:
await getDailyRate()
Update
I've added a test with jsonplaceholder data:
async function getDailyRate(day: string): Promise<number> {
let data = await fetchDailyRates();
let userId = data?.['userId'];
console.log(userId, ` <--- userId ----`);
return 1;
}
const fetchDailyRates = async (): Promise<DailyRateType[]> =>
await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json();
const test = async () => {
let temp: number = 1;
temp = await getDailyRate('1'); // this is not complaining about the type
};