简体   繁体   中英

javascript/react fetch returning a promise instead of result

I am quite new to coding in React/JS (or any async language for that matter) and am having trouble getting an API fetch function to return the result rather than the promise.

The fetch function is:

    export const i_sGETOrg = async () => {
        const Cookie = new Cookies();
        await fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
            method: "GET",
            headers: {
                Authorization: "Bearer " + Cookie.get("JWT"),
            },
        }).then((response) => {
            response.json().then((result) => {
                console.log(result);
                return result;
            });
        })
        .catch((error) => {
            APIErrorHandler(error);
        });
    };

This is being called from an click handling function in a separate component:

const DevOrganisations = () => {
    const [newOrganization, setNewOrganization] = useState("");
    const [orgs, setOrgs] = useState([]);

    //get the organisations for user when component mounts
    useEffect(() => {
        setOrgs(i_sGETOrg());
    }, []);

    //handle submit a new organization to API
    const handleSubmit = (event) => {
        event.preventDefault();
        i_sPOSTCreateOrg(newOrganization);
    };

    //handle get list of organizations from API
    const handleGetOrg = async () => {
        setOrgs(i_sGETOrg());
        console.log(orgs);
    };

    //handle log list of organizations to the console
    const handleLogOrgs = () => {
        console.log(orgs);
    };

    return (
        <div className="container">
            <h3>This is the development ORGANISATIONS page</h3>
            <button onClick={handleGetOrg}>Get Organisations</button>
            <button onClick={handleLogOrgs}>Console.log Orgs</button>
            <form onSubmit={handleSubmit}>
                <label>
                    Organization Name:
                    <input
                        type="text"
                        name="CreateOrgName"
                        value={newOrganization}
                        defaultValue=""
                        onChange={(e) => setNewOrganization(e.target.value)}
                    />
                </label>
                <input type="submit" value="Submit" />
            </form>

            <p>Your org is:</p>
            {newOrganization && <p>{newOrganization}</p>}

            <OrgsListDisplay orgs={orgs} />
        </div>
    );
};

export default DevOrganisations;  

How can I make handleGetOrg function wait for i_sGetOrg to return the result so setOrgs doesn't receive the promise? Or should I be tackling the state change completely differently?

When I click the Get Organisations button the following is printed to the console:

Promise { <state>: "fulfilled", <value>: undefined }
DevOrganisations.js:27
Array(21) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]

Additionally, I added a button to get the orgs value, but this logs:

Promise { <state>: "fulfilled", <value>: undefined }

Any help with this would be greatly appreciated.

Thanks:)

Greg

Looks like is the issue is that you don't return the result of the fetch request. fetch returns a Promise by design. You can either await its resolved/rejected value or use a Promise chain of then-ables. You should avoid mixing the two though.

export const i_sGETOrg = async () => {
    const Cookie = new Cookies();
    try {
      const response = await fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
          method: "GET",
          headers: {
              Authorization: "Bearer " + Cookie.get("JWT"),
          },
      });
      const result = await response.json();
      return result;
    } catch(error) {
        APIErrorHandler(error);
    };
};

Alternatively you can directly return the Promise chain returned from the fetch request. In this case i_sGETOrg doesn't need to be declared async and it still returns a promise that is settled later. Don't forget to return the next Promise from extracting the JSON data from the response.

export const i_sGETOrg = () => {
    const Cookie = new Cookies();
    return fetch(process.env.REACT_APP_APIADDRESS + "/api/v1/organizations/", {
        method: "GET",
        headers: {
            Authorization: "Bearer " + Cookie.get("JWT"),
        },
    })
        .then((response) => response.json())
        .then((result) => {
            console.log(result);
            return result;
        })
        .catch((error) => {
            APIErrorHandler(error);
        });
};

You want to actually wait for this resolved response though.

//handle get list of organizations from API
const handleGetOrg = async () => {
    setOrgs(await i_sGETOrg());
};

or

//handle get list of organizations from API
const handleGetOrg = () => {
    i_sGETOrg().then(res => setOrgs(res));
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM