I am building a basic context where I getting a response from an api that i build, simple one no auth and headers. Yet when I am trying to set the state value of the api response data the state value seems to be empty i.e. the default value of the useState hook;
Following is the api response;
[{
"id": "C8144412-E7BE-4CC4-BB0A-294938E38BD6",
"appName": "some App",
"p1AlertCount": 1,
"p2AlertCount": 2,
"appScore": 20,
"appStatus": true,
"message": "up and running"},
...
]
the below is the context api code;
import { createContext, useContext, useEffect, useState } from "react";
import AppStatus from "./types";
import axios from "axios";
const AppContext = createContext<AppStatus[] | null>(null);
const api_endpoint: string = `http://localhost:5289/AppStatus`;
const AppProvider = ({ children }: { children: React.ReactNode }) => {
const [isLoading, setLoading] = useState<boolean>(true);
const [fetchedData, setFetchedData] = useState<AppStatus[]>([]);
const fetchData = async (url: string) => {
try {
const response = await axios.get(url);
const appData: AppStatus[] = (await response.data) as AppStatus[];
if (response.status != 200 || response.statusText != "OK") {
throw new Error("failed to fetch");
}
setLoading(false);
setFetchedData(appData);
console.log(appData);
console.log(fetchedData);
} catch (error) {
throw new Error(`error is ${error}`);
}
};
useEffect(() => {
fetchData(api_endpoint);
}, []);
return (
<AppContext.Provider value={{ isLoading, fetchedData }}>
{children}
</AppContext.Provider>
);
};
const useGlobalContext = () => {
return useContext(AppContext);
};
export { AppContext, AppProvider, useGlobalContext };
response type set in the react proj;
export default interface AppStatus {
id: string;
appName: string;
p1AlertCount: number;
p2AlertCount: number;
appScore: number;
appStatus: boolean;
message: string;
}
API model;
namespace App_Health_Mock_API.Model
{
public class AppDataModel
{
public required string Id { get; set; }
public required string AppName { get; set; }
public required int P1AlertCount { get; set; } = 0;
public required int P2AlertCount { get; set; } = 0;
public required int AppScore { get;set; }
public required Boolean AppStatus { get; set; } = true;
public required string Message { get; set; }
}
}
I need help on how to set the value of my state value i.e. fetchedData to the appData(axios response.data)
I tried to type safe the response data and the state value as much as I could, loged the response data to double check if I am getting the correct array, and I am getting it. Only expectation is to set the value of the “fetchedData” to the appData value.
2
You made mistake for returned values in typings for the context and you don’t need to await the response.data
you already get a response with await axios.get
. Using of try/catch block is enough and you don’t need to check for response.status and response.statusText.
Modified example:
import { createContext, useContext, useEffect, useState } from 'react';
import AppStatus from './types';
import axios from 'axios';
interface IAppContext {
isLoading: boolean;
fetchedData: AppStatus[];
}
const AppContext = createContext<Partial<IAppContext>>({});
const AppProvider = ({ children }: { children: React.ReactNode }) => {
const [isLoading, setLoading] = useState<boolean>(true);
const [fetchedData, setFetchedData] = useState<AppStatus[]>([]);
useEffect(() => {
(async () => {
try {
const response = await axios.get<AppStatus[]>(
'http://localhost:5289/AppStatus'
);
setLoading(false);
setFetchedData(response.data);
} catch (error) {
setLoading(false);
console.error(error);
}
})();
}, []);
return (
<AppContext.Provider value={{ isLoading, fetchedData }}>
{children}
</AppContext.Provider>
);
};
const useGlobalContext = () => {
return useContext(AppContext);
};
export { AppContext, AppProvider, useGlobalContext };