Skip to content
Advertisement

React.Js and Typescript how to read data from JSON?

everyone.

I am using MongoDB with mongoose and React.Js. I have a page where the user can display a post.

I am sending fetch request to the backend where I am getting this json data as response.

 {
        "post": {
            "_id": "62cd5b5ef2a39582f96ad514",
            "title": "asdadsad",
            "description": "sdasdasdasda",
            "imageURL": "image 1",
            "creator_id": "62cd5b1bf2a39582f96ad500",
            "createdAt": "2022-07-12T11:30:38.255Z",
            "updatedAt": "2022-07-12T11:30:38.255Z",
            "__v": 0,
            "id": "62cd5b5ef2a39582f96ad514"
        }
    }

And on the frontend I am using Fetch API, to get this data, what I am trying to do is I want to be able to read every single key and value from the JSON response as I want to use this data to display title, content etc…

  const { isLoading, error, sendRequest, clearError } = useHttpRequest();
  const [getPost, setPost] = useState([]);
  const userID = useParams().id;

  useEffect(() => {
    const fetchPosts = async () => {
      try {

        const url: string = `http://localhost:8000/api/posts/${userID}`;
        const responseData = await sendRequest(url);

       console.log(responseData);
       setPost(responseData);

      } catch (err) { }}

      fetchPosts();
  }, [sendRequest]);

Now I had tried using the getPost.map(…….), however I got error that said getPost.map is not a function event when I did setPost(responseData.post) I got the same error. So how can I access different data in the JSON response ?

In case this helps here is my sendRequest function. and this is my sendRequest that is located in totaly different file

const useHttpRequest = () => {

    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const activeHttpRequests: any = useRef([]);


    const sendRequest = useCallback( async (url: string, method: string = 'GET', body: any = null, headers: {} = {}) => {

        setIsLoading(true);
        const httpAbort = new AbortController();
        activeHttpRequests.current.push(httpAbort);

        try {
            const response = await fetch(url, {
                method: method,
                headers: headers,
                body: body,
                signal: httpAbort.signal //FIX FOR CROSS REQUEST SENDING
              });
  
            const responseData = await response.json();
            
            activeHttpRequests.current = activeHttpRequests.current.filter((requests: any) => requests !== httpAbort);
            if (!response.ok){
                throw new Error("Error fetch failed !");
            }

            setIsLoading(false);
            return responseData;
        } catch (err: any) {
            console.log(err.message)
            setError(err.message);
            setIsLoading(false);
            throw err;
        };
        
    }, [])

    const clearError = () => {
        setError(null);
    }

    useEffect(() => {
        return () => {
            activeHttpRequests.current.forEach((abortRequest: any) => abortRequest.abort()) //ABORT CURRENT REQUEST 
        };
    }, []);

    return { isLoading, error, sendRequest, clearError }
}

export default useHttpRequest

Advertisement

Answer

Your return Object would look something like this:

export interface Posts {
    post: Post[];
}

export interface Post {
    _id:         string;
    title:       string;
    description: string;
    imageURL:    string;
    creator_id:  string;
    createdAt:   Date;
    updatedAt:   Date;
    __v:         number;
    id:          string;
}

To simplify your work and make sure you get the correct data back, you should consider doing this below:

  const { isLoading, error, sendRequest, clearError } = useHttpRequest();
  const [getPost, setPost] = useState<Posts>([]);
  const userID = useParams().id;

  const fetchPosts = async () => {
    try {

      const url: string = `http://localhost:8000/api/posts/${userID}`;
      const responseData = await sendRequest(url);

     console.log(responseData);
     setPost(responseData);

    } catch (err) { }}


  useEffect(() => {
      fetchPosts();
  }, [sendRequest]);

  return (
    <div>
        <h1>get Data</h1>
        {getPost.post.map((value,index) => (
            <li key={`${index}-${value}`}>{value}</li>
        ))}
    </div>
)
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement