How wait for asynchronous function to complete

I am uploading an image in a form and the form is getting submitted to Firebase Database and I also want to send along the image URL to Firebase Database.

var {image} = this.state;
var {url} = this.state;
var that = this;

var storageRef = firebase.storage().ref('students_images/' + image.name);
storageRef.put(image).then(function(snapshot) {
  that.setState({
    url: snapshot.downloadURL
  });

});
var studRef = firebaseRef.child('students');
var newStudRef = studRef.push().update({
  name: val['name'].value,
  email: val['email'].value,
  age: val['age'].value,
  date: val['jdate'].value,
  course: val['course'].value,
  imgUrl: url
});

But the problem is that the image URL is coming from an asynchronous function and it takes a little bit giving back the URL, but the form is getting submitted immediately, so the value of imgUrl is setting undefined.

Upvotes: 0

Views: 280

Answers (2)

yadhu
yadhu

Reputation: 15642

The problem is that this statement that.setState({url: snapshot.downloadURL}); is executed in the callback and the form submission is outside the callback.

Although you will setState correctly after the snapshot response, the form submission code placed outside the callback gets executed while we are waiting for the response from our async code. In fact, form submission happens before you setState.

The solution is to execute the form submission code inside the async function's callback. Also keep in mind State Updates May Be Asynchronous.

So I recommend you do it as follows:

var { image, url } = this.state;
var storageRef = firebase.storage().ref('students_images/' + image.name);
var studRef = firebaseRef.child('students');

var that = this;
storageRef.put(image).then(function(snapshot) {

    var newStudRef = studRef.push().update({
        name: val['name'].value,
        email: val['email'].value,
        age: val['age'].value,
        date: val['jdate'].value,
        course: val['course'].value,
        imgUrl: snapshot.downloadURL
    });

    that.setState({ url: snapshot.downloadURL }); 

    // ... do more things with 'snapshot' or 'newStudRef'
});

Upvotes: 1

Vikramaditya
Vikramaditya

Reputation: 5584

submit your form inside then block.

var storageRef = firebase.storage().ref('students_images/' + image.name);
            storageRef.put(image).then(function (snapshot) {

                that.setState({url: snapshot.downloadURL});

                var studRef = firebaseRef.child('students');

            var newStudRef = studRef.push().update({
                name: val['name'].value,
                email: val['email'].value,
                age: val['age'].value,
                date: val['jdate'].value,
                course: val['course'].value,
                imgUrl: snapshot.downloadURL
            });
            });

Upvotes: 2

Related Questions