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

Time:07-13

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

CodePudding user response:

The map function is only present on arrays, but the data you gave is an Object. You can access it using subscript notation or iterate over the keys of the object.

const data = {
    "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"
    }
}

// access a single field
console.log(data.post.title) // asdadsad

// iterate over all fields in "post"
Object.keys(data.post).forEach((key, value) => console.log(`${key}: ${data.post[key]}`))

CodePudding user response:

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>
)
  • Related