Abdulrahman sabah
Abdulrahman sabah

Reputation: 77

how to set Loading while api call in reactjs?

For some reason, the loading state doesn't change when I'm using this method to fetch from the API.

How to display "Loading..." while the call is running.

const [product, setProduct] = useState({});
const [loading, setLoading] = useState(false);
const productId = 1;

const fetchProduct = () => {
  setLoading(true);
  //here commerce is my api, so i fetched the product details and set it to the product state
  commerce.products.retrieve(productId).then(data => setProduct(data));
  setLoading(false);
}

useEffect(() => {
  fetchProduct();
})

if (loading) {
  return (
    <span>Loading...</span>
  )
}

return (
  <h1>{product.name}</h1>
)

Upvotes: 1

Views: 8503

Answers (4)

Quentin
Quentin

Reputation: 944294

Forget about loading.

You can infer if the data is loading or not from the value of product.

const Component = () => {
    const [product, setProduct] = useState(null);

    useEffect(() => {
        const getProducts = async () => {
            const data = await commerce.products.retrieve(productId)
            setProduct(data);
        };
        getProducts();
    }, []);

    if (product === null) {
        return <span>Loading...</span>;
    }

    return <h1>{product.name}</h1>;
}

If you really wanted to use a separate loading variable then you would have it default to true and set it to false at the same time you give a value to product.

Upvotes: 0

Ritchi
Ritchi

Reputation: 311

I think there's two way for doing it corresponding of your code.

First, this one:

const [isLoading, setIsLoading] = useState(false);

const handleFetch = () => {
  setIsLoading(true);
  someApiCall().then((r) => {
    setIsLoading(false);
  });
};

Or

const [isLoading, setIsLoading] = useState(false);

const handleFetch = async () => {
  setIsLoading(true);
  await someApiCall();
  setIsLoading(false);
};

Upvotes: 1

Sabir
Sabir

Reputation: 179

you didn't use async await at all but if you donn't wana use async await then u should use following

 const fetchProduct = () => {
    setLoading(true);
    //here commerce is my api, so i fetched the product details and set it to the product state
    commerce.products.retrieve(productId).then(data => {
      setProduct(data);
      setLoading(false);
      }).catch(() => {
        setLoading(false);
     })
    

    }

Upvotes: 0

Davide Turini
Davide Turini

Reputation: 151

You have to set the complete state inside the promise result just after retrive the products

const fetchProduct = () => {
    setLoading(true);
    commerce.products.retrieve(productId)
        .then(data => {
                       setProduct(data)
                       //HERE
                       setLoading(false);
                       });
}

Upvotes: 1

Related Questions