1
votes

the question is clear, I need to display an alert with the elements of a firebase list.

Alert creation

let alert = this.alertCtrl.create({
      title: 'Elegir repartidor',
      inputs: [],
      buttons: [
        {
          text: 'Asignar',
          handler: data => {
              this.firebaseService.updateOrderAssignDeliverymen(orderKey, data);
              },
          role: 'cancel'
        }
      ]
    });
    this.firebaseService.getDeliveryMenFillAlert(alert).then(res => alert.present());

Alert Inputs creation

getDeliveryMenFillAlert(alert: AlertController) {
    this.afd.list('/users', ref => ref.orderByChild('role').equalTo('Repartidor'))
      .snapshotChanges()
      .subscribe( res =>
        res.map(action => {
          alert.addInput({
            type: 'radio',
            label: action.payload.val().name,
            value: action.key
          })
        }),
        error => console.log(error));
  }

After reading many questions, quite surprised about the number of different approaches... and more surprised that I haven't been able to success with one.

First attempt

Created a second function with a simple promise return to try. Everything is working ok.

getDeliveryMenFillAlert2(alert: AlertController) {
return Promise.resolve(true);
//return Promise.reject(false);

}

this.firebaseService.getDeliveryMenFillAlert2(alert)
  .then(resolve => console.log('Resolve: ' + resolve),
        reject => console.log('Reject: ' + reject));

Second attempt

Tried to insert this simple return in my original function an of course change the call to this original function.

getDeliveryMenFillAlert(alert: AlertController) {
this.afd.list('/users', ref => ref.orderByChild('role').equalTo('Repartidor'))
  .snapshotChanges()
  .subscribe( res =>
    res.map(action => {
      alert.addInput({
        type: 'radio',
        label: action.payload.val().name,
        value: action.key
      });
      return Promise.resolve(true);
    }),
  error => {
    console.log(error)
    return Promise.reject(false);
  });

}

But an error is thrown "TypeError: Cannot read property 'then' of undefined".

Third attempt

Added return Promise to the function. Same error.

getDeliveryMenFillAlert(alert: AlertController): Promise {

Fourth attempt Reading one of the questions it introduced the async/await concept, so I introduced "async" to the function and "await" to the response.

async getDeliveryMenFillAlert(alert: AlertController): Promise {

return await Promise.resolve(true);

Recibe another error "Uncaught Error: Module parse failed: The keyword 'yield' is reserved".

Last try

Don't know why but just deleted "await" but keeping "async" in the function, it doesn't retrieve any error (great) but the console.log of the call prints "Resolve: undefined".

So it seems that is resolving but doesn't work.

I also tried to return "new Promise..." and "true.toPromise()" instead of "return Promise.resolve(true)", I read it somewhere but nothing is working. Any help please, I'm trying hard but not able to.

FINAL SOLUTION (can't post it as response)

getDeliveryMenFillAlert(alert: AlertController) {
    return new Promise(resolve => {
    this.afd.list('/users', ref => ref.orderByChild('role').equalTo('Repartidor'))
      .snapshotChanges()
      .subscribe( res =>
        res.map(action => {
          alert.addInput({
            type: 'radio',
            label: action.payload.val().name,
            value: action.key
          });
          resolve(alert);
        }))
      });
   }

and the call would be:

this.firebaseService.getDeliveryMenFillAlert2(alert)
      .then(resolve => alert.present());
1

1 Answers

1
votes

I'm guessing you're calling alert.present() just after this call :

this.firebaseService.getDeliveryMenFillAlert(alert);

If so, you probably want to wait for your callback to end before displaying the alert.

  • A quick fix could be to present the alert after setting the inputs :
alert.addInput({
  type: 'radio',
  label: action.payload.val().name,
  value: action.key
});
alert.present();
  • But a better way would be to return a promise from your getDeliveryMenFillAlert function. And call alert.present() in the sucess callback :
this.firebaseService.getDeliveryMenFillAlert(alert)
    .then(res => alert.present());