jonhz
jonhz

Reputation: 53

navCtrl.push not working in Ionic3

I'm making an app with Ionic that uploads an image to my Firebase storage. When the upload is complete, the app should redirect the user to the WelcomePage. The upload is working, but for some reason the user is not being redirected. Take a look at the end of the code: The console does shows Uploaded, but this.navCtrl.push(WelcomePage) is not working.

upload() {
  let storageRef = firebase.storage().ref();

  const filename = "profilePic";

  const imageRef = storageRef.child(`images/${filename}.jpg`).putString(this.profilepicture, firebase.storage.StringFormat.DATA_URL);

  imageRef.on('state_changed', function(snapshot){

    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
    console.log('Upload is ' + progress + '% done');
    switch (snapshot.state) {
      case firebase.storage.TaskState.PAUSED:
        console.log('Upload is paused');
        break;
      case firebase.storage.TaskState.RUNNING:
        console.log('Upload is running');
        break;
    }
  }, function(error) {
    // Handle unsuccessful uploads
  }, function() {
    // Handle successful uploads on complete
    console.log('Uploaded');
    this.navCtrl.push(WelcomePage);
  });

 }

Upvotes: 2

Views: 1083

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

Most likely the meaning of this is different in your callback. If that is the case, you can either put the navCtrl in a separate variable, or you can use fat-arrow functions.

Put the navCtrl in a separate variable

The meaning of this depends on the function that you use it in. Since the callbacks are separate functions, they also have their own value for this. So inside the callback this.navCtrl doesn't exist.

The solution is to capture the value you need into a unique variable name before the callback:

var navCtlr = this.navCtrl;
imageRef.on('state_changed', function(snapshot){
  var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
  document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
  console.log('Upload is ' + progress + '% done');
  switch (snapshot.state) {
    case firebase.storage.TaskState.PAUSED:
      console.log('Upload is paused');
      break;
    case firebase.storage.TaskState.RUNNING:
      console.log('Upload is running');
      break;
  }
}, function(error) {
  // Handle unsuccessful uploads
}, function() {
  // Handle successful uploads on complete
  console.log('Uploaded');
  navCtrl.push(WelcomePage);
});

Use fat-arrow functions

ES6 adds a new way to define callback functions using a fat-arrow notation. In your code function(error) { can be replace with (error) => {. In addition to being slightly shorter, the new notation actually maintains the meaning of this inside the callback. So:

imageRef.on('state_changed', (snapshot) => {
  var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
  document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
  console.log('Upload is ' + progress + '% done');
  switch (snapshot.state) {
    case firebase.storage.TaskState.PAUSED:
      console.log('Upload is paused');
      break;
    case firebase.storage.TaskState.RUNNING:
      console.log('Upload is running');
      break;
  }
},(error) => {
  // Handle unsuccessful uploads
}, () => {
  // Handle successful uploads on complete
  console.log('Uploaded');
  this.navCtrl.push(WelcomePage);
});

Upvotes: 2

Related Questions