Home > Net >  json response from mock server not printing but is in the console
json response from mock server not printing but is in the console

Time:08-22

I am trying to learn react, and I am making a successful API call, but it only prints in the console. I found examples but many of them recommended to use setData(json) but I am not able to use it because the file is a list of export async function which was also recommended.

export async function GetHellWorld() {
    return fetch(`http://localhost:8080/api`, {
        method: "Get",
        headers: {
            "Content-type": "application/json; charset=UTF-8"
        }
    }).then(response => response.json())
        .then(json => {
            console.log(json)
        })
        .catch(error => (console.log(error)))
}

and the component

function Test(thisArg, argArray) {

    const result = GetHellWorld.apply()

    return (
        <div className="App">
            {JSON.stringify(result)}
        </div>
    );
}

export default Test;

In the console I see "Hello World" but in the browser is get just {}.

Two questions:

  1. How can I bind the JSON response to an object so I can do something like result.name.

  2. Is this the correct was to call the await function? const result = GetHellWorld.apply()

---- update ----

I decided to try axios because I want to make multiple calls in one file.

const axios = require('axios');

export class AppService {

    public async GetHelloWorld(): Promise<any> {
        const response = await axios.get(`http://localhost:8080/api`, {
            method: "Get",
            headers: {
                "Content-type": "application/json; charset=UTF-8"
            }
        }).catch(() => console.log("Issue in GetHelloWorld"))

        return response.data
    }

}

component

import React from 'react'; import {AppService} from "../services/app.service";

function Movies() {

    const api = new AppService()

    const hello = async () => {
        const response = await api.GetHelloWorld();
        console.log("The response: "   response)
    }

    return (
        <div className="App">
            {JSON.stringify(hello)}
        </div>
    );
}

note I had to add typescript support.

For whatever reason I get

Module not found: Error: Can't resolve '../services/app.service' in '/Users/miketye/programming/test-react/src/components'

CodePudding user response:

While the other answer about using a custom hook can work, I would not recommend it while you're still leaning React.

Look up how to use the "useEffect" hook, that's generally how you want to do any sort of loading logic in React.

First off, you need to fix your async function so it actually returns a value:

// style/convention note, but non-component functions should not start with a capital letter
export async function getHelloWorld() {
    return fetch(`http://localhost:8080/api`, {
        method: "Get",
        headers: {
            "Content-type": "application/json; charset=UTF-8"
        }
    }).then(response => response.json())
        .then(json => {
            return json // will cause this function to return a Promise of type "string", since we're in an async function 
        })
        // better to just let the error get thrown here, for testing 
}

Then use it like this:

function Test(thisArg, argArray) {

    [fetchResult, setFetchResult] = useState(undefined) // look up useState. State is how you have values that change over time in a resct component

    useEffect(() => {

        async function fetchData() {
           const data = await getHelloWorld()
           setFetchResult(data)
        } 

        fetchData() 

    }, []) 
    // look up useEffect. Since the second argument (the "dependency array") is empty, useEffect will fire only once, after the component loads 

    return (
        <div className="App">
            {result ? JSON.stringify(result) : "no result yet"}
        </div>
    );
}

export default Test;

CodePudding user response:

You can use a custom hook for this purpose:

import { useState } from "react";

const useFetchData = () => {
    const [data, setData] = useState(null);

    const fetchData = () => {
        fetch("http://localhost:8080/api", {
            method: "Get",
            headers: {
                "Content-type": "application/json; charset=UTF-8"
            }
        }).then(response => response.json())
            .then(json => { setData(json); })
            .catch(error => { console.log(error); })
    }

    useEffect(() => {
        fetchData();
    }, []);

    return { data, fetchData };
}

export default useFetchData;

And then call it in your component:

import useFetchData from "@/hooks/useFetchData";

const Test = () => {
    const { data, fetchData } = useFetchData();
    // CALL fetchData IF YOU WANT TO UPDATE THE CURRENT STATE

    return (
        <div className="App">
            {data && JSON.stringify(data)}
        </div>
    );
}

export default Test;
  • Related