Angular method returns as undefined rather than JS

2019-09-12 23:57发布

问题:

I have a getUser method within an Authentication provider (working in Ionic 2):

  getUser(uid: string): any {
    var toReturn;

        firebase.database().ref('/userProfile').orderByKey().equalTo(uid).once("value", function(snapshot){
          toReturn = snapshot.val();
          console.log("getUser = " + JSON.stringify(toReturn));
        });

        return toReturn;
      }

It retrieves a user object from firebase. It gets output correctly with the console.log providing it exists and is saved in the toReturn variable.

Below is the ItemDetailPage class however when I log the value of the same method, it returns undefined.

import { Component } from '@angular/core';
import { NavParams} from 'ionic-angular';
import { Auth } from '../../providers/auth/auth';

@Component({
  templateUrl: 'build/pages/item-detail/item-detail.html',
  providers: [Auth]
})
export class ItemDetailPage {
  private title;
  private description;
  private author;

  constructor(private navParams: NavParams, private _auth: Auth) {
    this.title = this.navParams.get('item').title;
    this.description = this.navParams.get('item').description;
    this.author = _auth.getUser(this.navParams.get('item').author);
    console.log("item-detail.ts = " + JSON.stringify(this.author));
    //_auth.getUser('123');
  }

}

I'm new to Angular and trying to learn as I go along, so this is probably something quite simple I'm missing out. However, why does the JSON object not get returned/passed back? I need it to utilise the values queried from the database.

Thanks

回答1:

What you are missing is that the Firebase method is running assincronously. So, it does return a promise instead of a value. That's why you get the returned value as a callback.

What you should do is: return the firebase promise in your service (or a new one in case you want to do something with the data before returning it to the controller). Then you want to create a callback function into the controller.

return firebase.database().ref('/userProfile').orderByKey().equalTo(uid).once("value", function(snapshot){});

// Controller

_auth.getUser(this.navParams.get('item')).then(function(snapshot){
    ...
});

You should take a look into how promises work in plain javascript:

http://andyshora.com/promises-angularjs-explained-as-cartoon.html

And then how they are used in the NG2 style

http://coenraets.org/blog/2016/02/angular2-ionic2-data-services-promises-observables/