Manoj Shetty
Manoj Shetty

Reputation: 73

Execute one function after another using async and await in react

const AddNew = (props) => {
  const [photoUrl, setPhotoUrl] = useState([]);
  const [title, setTitle] = useState();
  const [photos, setPhotos] = useState([]);

  useEffect(() => {
    axios.get("http://localhost:80/newItem").then((res) => {
      console.log(res.data);
    });
  });
  const uploadPhoto = () => {
    console.log("one");
    const storage = fire.storage();
    const reference = storage.ref();
    photos.forEach((photo) => {
      reference
        .child(photo.name)
        .put(photo)
        .then(
          (snapShot) => {
            snapShot.ref.getDownloadURL().then((url) => {
              console.log(url);
              setPhotoUrl((photoUrl) => [...photoUrl, url]);
            });
          },

          (err) => {
            console.log(err);
          }
        );
    });
  };

  const addItems = () => {
    console.log("two");
    const photo = photoUrl;
    const uploadData = axios
      .post("http://localhost:80/newItem", {
        photos: photo,
        title: title,
      })
      .then((res) => alert(res))
      .catch((e) => alert(e));
    window.location.reload(false);
  };
  const uploadData = async () => {
    await uploadPhoto;
    await addItems;
  };
  return (
    <div>
      <Container>
        <h4
          className="text-center mb-5 mt-5"
          style={{ borderBottom: "1px solid black" }}
        >
          Add a new Product
        </h4>
        <div style={{ width: "75%", margin: "0 auto" }}>
          <Row className="text-center">
            <Col sm={12} lg={12} md={12}>
              <Form.Group>
                <Form.File
                  label="upload upto 5 images"
                  multiple
                  onChange={(e) => {
                    if (Array.from(e.target.files).length <= 4) {
                      const img = Array.from(e.target.files);
                      setPhotos(img);
                    } else {
                      alert("You can select maximum 5 Images");
                      e.target.value = null;
                    }
                  }}
                  accept=".jpg"
                />
              </Form.Group>
              <Form.Group controlId="exampleForm.ControlInput1">
                <Form.Label>Title</Form.Label>
                <Form.Control
                  type="text"
                  placeholder="Title"
                  value={title}
                  onChange={(e) => setTitle(e.target.value)}
                />
              </Form.Group>

              <Button variant="outline-primary" onClick={uploadData}>
                Submit
              </Button>
            </Col>
          </Row>
        </div>
      </Container>
    </div>
  );
};
export default AddNew;

In the above code On click of button, I'm going to uploadData function. Where in uploadData function, the uploadPhoto function should execute first and then it should set the URL to the setPhotoUrl hook. And after storing the image and getting the url, addItems function should execute where it posts the title and url of photo to the express server. But it is not happening as expected.

Upvotes: 1

Views: 7236

Answers (2)

Gh05d
Gh05d

Reputation: 8982

You have to convert your functions to async functions in order to be able to await them. So do instead of

const uploadPhoto = () => { and const addItems = () => {

this const uploadPhoto = async () => { and this const addItems = async() => {

Then change your uploadData function to this:

  const uploadData = async () => {
    await uploadPhoto();
    await addItems();
  };

Upvotes: 0

Siddhant Varma
Siddhant Varma

Reputation: 594

You can wrap your addItems method's invocation inside a useEffect and conditionally fire it only if you have set photoUrl and title.

useEffect(()=>{
 if(title && photoUrl)
 addItems();
},[title,photoUrl])

After this, you should set your title and photoUrl back to an empty string or null. So inside your addItems method add the following line

 const addItems = () => {
    console.log("two");
    const photo = photoUrl;
    const uploadData = axios
      .post("http://localhost:80/newItem", {
        photos: photo,
        title: title,
      })
      .then((res) =>{ 
            alert(JSON.stringify(res))
            setPhotoUrl('');
            setTitle('');
      })
      .catch((e) => alert(e));
    window.location.reload(false);
  };

Upvotes: 1

Related Questions