Angular 2 w / TypeScript Firebase API返回服务中的对象数组,但在组件中未定义

时间:2016-11-29 15:28:51

标签: javascript angular firebase firebase-realtime-database

我正在尝试在Angular 2应用程序中使用Firebase API。

以下是我服务中的内容:

fbGetData() {
        firebase.database().ref('/path/to/data').on('value',(snapshot) => {
            this.data = snapshot.val();
            console.log(this.data); //This logs my data
            return this.data;
        })
    }

这就是我在我的组件中所拥有的:

ngOnInit() {
        this.data = this.dataService.fbGetData();
        console.log(this.data); //This logs undefined
    }

组件记录未定义,然后服务记录对象数组。提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

正如@jonrsharpe评论的那样:Firebase从其服务器异步检索数据。您的浏览器不会等待此结果,因为这会阻止用户执行其他操作。因此,您无法从fbGetData返回数据,因为它尚未加载。

有两种方法可以使用异步加载:

  1. 使用回叫
  2. 返回承诺
  3. 使用回调

    异步加载的技巧是从#34重新构建解决方案;首先获取数据,然后打印它"加载数据后,打印出来"。

    在代码中,这转换为:

    fbGetData() {
        firebase.database().ref('/path/to/data').on('value',(snapshot) => {
            this.data = snapshot.val();
            console.log(this.data);
        })
    }
    
    fbGetData();
    

    因此,日志记录现在完全在on()回调中。

    当然,您可能希望在不同时间对数据执行不同的操作,因此您可以将回调传递给fbGetData()

    fbGetData(callback) {
        firebase.database().ref('/path/to/data').on('value',(snapshot) => {
            this.data = snapshot.val();
            callback(this.data);
        })
    }
    
    fbGetData(data => console.log(data));
    

    当然,在这个阶段,您应该考虑是否应该使用快照调用自己的回调:

    fbGetData(callback) {
        firebase.database().ref('/path/to/data').on('value',callback);
    }
    
    fbGetData(data => console.log(data.val()));
    

    返回承诺

    在上面的示例中,数据将在最初从服务器加载时以及服务器上的数据发生更改时打印。这是Firebase数据库神奇的一部分:它同步当前值和对该值的任何更改。

    如果您只关心当前值,也可以使用once()。此方法可以进行回调,但也可以返回promise。这意味着您可以从fbGetData返回一些内容:

    fbGetData() {
        var promise = firebase.database().ref('/path/to/data').once('value');
        return promise;
    }
    
    fbGetData().then(snapshot => console.log(snapshot.cal());
    

    使用此代码段时,只会打印一次(最多)一次,因为您正在使用once()

答案 1 :(得分:1)

您可以尝试使用subscribe方法获取数据。可以订阅,映射Observable并将其转换为JSON。

查看代码并查看是否可以获得某些内容。

public sessions(): any {
    return this.http.get('api/ResultsAPI')         //.get('api/vehicles.json')
        .map(
        (response: Response) => <any>response.json())
        .do
        (
        response => response
        );
}

要拨打该服务,请使用此

this.ApiService.sessions().subscribe(
data =>  {
   this.api = data;
   this.getdata(this.api);
}
);