【问题标题】:Angular 2 w/ TypeScript Firebase API returns array of objects in service but undefined in component带有 TypeScript Firebase API 的 Angular 2 返回服务中的对象数组,但在组件中未定义
【发布时间】:2016-11-29 15:28:51
【问题描述】:

我正在尝试在我的 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
    }

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

【问题讨论】:

  • fbGetData 是异步的,它不返回数据。

标签: javascript angular firebase firebase-realtime-database


【解决方案1】:

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

异步加载有两种方式:

  1. 使用回调
  2. 返回一个承诺

使用回调

异步加载的技巧是将您的解决方案从“首先获取数据,然后打印它”重新构建为“只要加载数据,就打印它”。

在代码中,这转换为:

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());

使用这个 sn-p 值只会(最多)打印一次,因为您使用的是once()

【讨论】:

  • 我知道我现在哪里出错了。非常感谢您抽出宝贵时间提供帮助
【解决方案2】:

您可以尝试订阅方法来获取数据。 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);
}
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2016-12-25
    • 2015-12-23
    • 1970-01-01
    • 2018-05-29
    相关资源
    最近更新 更多