React using API call

Hi Guys, i am trying to build a project using React abd i was just trying to use the API calls in the React but i got stuck on the below code as it is returning an Error(items.then is not a function), i am using .then method as its an Async function returning the value of new state, i cant think any other thing other .then to get the data from the API call to show, as i think there is some thing i am not correctly defining in return statement from the below code…

//Snippet from the Shope.js

    <div>

{items.then((items)=>(
   <p>{items.data}</p>
  ))}
    </div>any advise please

Note: items1.data is an object and that object has different information that i am looking to show in the DOM.

// All the code for Shop.Js

import React, { useState, useEffect } from "react";

import "./App.css";

import { Link } from "react-router-dom";

// whenver clicked shop then below function will be called

function Shop() {

  useEffect(() => {

    fetchItem();

  }, []);

  const [items, setItems] = useState([]);

  const fetchItem = async () => {

    const data1 = await fetch(

      "https://corona-virus-stats.herokuapp.com/api/v1/cases/general-stats"

    );

    const items1 = await data1.json();

    console.log(data1); // console @ shop.js:20 below snap shot

    console.log(items1); // console @ shop.js:20 below snap shot

    console.log(items1.data);

    setItems(items1.data);

  };

  return (

    <div>

{items.then((items)=>(
   <p>{items.data}</p>
  ))}
    </div>

  );

}

export default Shop;

The below is the Object data that i get as response from the API
Thanks guys for helping out.

image

i have tried few things and as i understand now the objects cant be displayed in the JSX format but can access its indivisual value by using . method.

i can populate the screen now successfully with the values but have to write all the items keys {…} from the objects as below.

Is any one can please advise if there is any effective method that i can use to display all the values automatically in it along with the description, like
active_cases_critical_percentage: 2.0
items.active_cases_mild_percentage:98.0

Thanks in advance.

return (

    <div>

      <p>{items.active_cases_critical_percentage},</p>

      <p>{items.active_cases_mild_percentage},</p>

    </div>

  );

}

For the first bit, its fetchItem() which is async, so the return value from that (a promise) is what you’d call then() from. But you don’t need a then because its not returning anything. Instead you’re calling setItems() inside that function which automatically updates the state and re-renders. Then you’d just refer to items directly in the markup.

The listing out the keys and values, you can do that using Object.entries(). That returns an array of arrays, each a key-value pair (key in index 0, value in index 1). Then you can loop through that and output your <p> elements.

<div>
  {Object.entries(items).map(entry => {
    let key = entry[0];
    let value = entry[1]
    // or, instead of ^, you could also define
    // the params as `([key, value]) => {`

    return <p key={key}>{key}: {value}</p>
  })}
</div>
1 Like

yes it makes sense now and it worked, Thanks Pal :slightly_smiling_face:

Hey guys,

i am a bit puzzled with the logic when reading the below code, although the code is working but not exactly as i would like it to behave.

As i understand useEffect is used to invoke the function, but in the below code, once the form is sumbitted (onSubmit={credentialVerify}) it will call the credentialVerify() function as below, but still the code doesnt work unless i use the useEffect statement.

  • but the problem is it doesnt wait for me to enter my credentail and as soon as i go to the Signin page it will fetch the API’s and show the result in the windows,
    import React, { useState, useEffect } from "react";
    import "../App.css";
    import { Link } from "react-router-dom";

    function Signin() {
      // empty string as default initial parameter ('')
      const [name, setName] = useState("");
      const [password, setPassword] = useState("");
      const updateName = (e) => {
        setName(e.target.value);
      };
      const updatePassword = (e) => {
        setPassword(e.target.value);
      };
      const [items, setItems] = useState([]);
      useEffect(() => {
        credentialVerify();
      }, []);
      const credentialVerify = async () => {
        const data1 = await fetch("http://localhost:5000/api/customers");
        const incomingdata = await data1.json();
        console.log(data1);
        console.log(incomingdata);
        console.log(incomingdata);
        console.log(incomingdata.data);
        console.log(name, password);
        setItems(incomingdata);
      };
      return (
        <div>
          <div>
            {
              <form className="formstyle" onSubmit={credentialVerify}>
                <input
                  type="text"
                  placeholder="Username"
                  name="username"
                  value={name}
                  onChange={updateName}
                />
                          
                <input
                  type="text"
                  placeholder="Password"
                  name="password"
                  value={password}
                  onChange={updatePassword}
                />
                <button type="submit">Submit</button>
              </form>
            }
          </div>
          <div>
           
            {items.map((entry) => {
              let key = entry.email;
              let valuefirst = entry.firstName;
              let valuelast = entry.created_at;
            
              return (
                <p key={key}>
                  {key}: {valuefirst}bb {valuelast}
                </p>
              );
            })}
          </div>
        </div>
      );
    }
    export default Signin;

Thanks a lot guys.

Just to mention i am not passing the event parameters in the async() call, as i was just trying to establish the two way communication first before edit my code again and send the real credential data.

one wired thing i came across is that for sure if i take the useEffect statement off, the credentialVerify function will not run at all as i don’t see any console.log… either then.
so definitely onSubmit={credentialVerify} is not working at all…although onChange={updateName} & {updatePassword} are working .

onSubmit as i understand dead simple so i am not sure where exactly what i am doing wrong…

Submit buttons submit the form, which means reloading the current page or loading a new page. This would happen immediately which wouldn’t allow your async credentialVerify to run. Why do you need it to call it at all if you call it in the useEffect? Or is it that you dont really want the useEffect and you want it to happen when you click submit? It may be that you don’t actually want a form then. Instead you might want to skip the form and just use a button that when clicked calls credentialVerify.

@senocular yes you correct, it was reloading the page and thats why i couldnt see the logs either.
i was actually trying to achieve a login form that pass the credentials to Node and then ultimately save it in DB.
I came across the pooling of SyntheticEvent in react and it doesnt allow Async to access the event so i have to call the Async function within the credentialVerify function and is now working as i expected. Thanks a lot.

below code snippet that get called when onSubmit={credentialVerify} trigger the function and now i am not using useEffect at all.

const credentialVerify = event => {
    event.preventDefault();

    (async () => {
      const incomingdata = await fetch("http://localhost:5000/api/customers")
        .then(res => res.json())
        .catch(e => e);
      console.log(incomingdata);
      console.log(name, password);
      setItems(incomingdata);
    })();
  };
  return (...................

A post was split to a new topic: JSON parsing in Express