【问题标题】:Return Array from Firebase snapshot method从 Firebase 快照方法返回数组
【发布时间】:2017-06-04 20:16:20
【问题描述】:

我正在连接到Firebase 并从给定位置检索数据,我想做的是循环通过snapshot.val() 构建和Array,返回Array,然后循环通过它component.html 并构建一个Dropdown

目前我很难弄清楚这种服务方法的语法,这是我当前的代码。 - 这是从app.component.ts 内的ngOnInit() 调用的

getExerciseOptions(): Array<Exercise> {

    const items: Exercise[] = [];

    this.exerciseDbRef2.on("value", (snapshot) => {

        snapshot.forEach((snap) => {
            items.push({
                id: snap.key,
                description: snap.val().description
            });
            return false;

        });
    });
}

所以this.exerciseDbRef2 指向Firebase 内的表,如下所示:

private exerciseDbRef2 = this.fire.database.ref('/exercise_description');

我目前收到的错误是

A function whose declared type is neither 'void' nor 'any' must return a value.

据我了解,所以当我将 return false 更改为 return items 时,新错误是:

Argument of type '(snap: DataSnapshot) => Exercise[]' is not assignable to parameter of type '(a: DataSnapshot) => boolean'.
Type 'Exercise[]' is not assignable to type 'boolean'. 

我已经研究过使用child_added,但据我了解,每次将新孩子添加到该位置时都会调用它,这不是我想要的。这个位置的孩子不会改变,也不会被添加。 - 也许我误解了“child_added”?

我对@9​​87654338@ 还很陌生,所以我刚开始学习,所以请随意,我还想提一下,如果我目前这样做的方式不正确,请带上它引起我的注意。

所以为了澄清:连接到Firebase,从给定位置检索所有孩子,即练习描述表,循环通过snapshot,构建一个Array并返回它。

然后在组件上循环通过Array 并构建Dropdown

有人可以解释一下我如何根据snapshot.val() 返回Array 吗?

【问题讨论】:

  • 那个 sn-p 看起来不完整。你有切碎的碎片吗?该错误意味着on 回调正在返回一个数组。而getExerciseOptions 函数被声明为返回Array&lt;Exercise&gt;,但什么也不返回。
  • @cartant 感谢您提前提供帮助,sn-p 正确。我对如何返回使用从Firebase 返回的值构建的数组的语法感到困惑。理想情况下,我想从此函数返回Array&lt;Exercise&gt;

标签: arrays angular typescript firebase firebase-realtime-database


【解决方案1】:

您不能从getExerciseOptions 返回数组,因为value 事件是异步的。

但是,你可以返回一个承诺:

getExerciseOptions(): Promise<Array<Exercise>> {
    return this.exerciseDbRef2
      .once("value")
      .then(snapshot => {
        const exercises: Exercise[] = [];
        snapshot.forEach(snap => {
            exercises.push({
                id: snap.key,
                description: snap.val().description
            });
            return false;
        });
        return exercises;
    });
}

然后你可以这样称呼它:

getExerciseOptions().then(exercises => console.log(exercises));

如果您不熟悉 Promise,您可能需要阅读 JavaScript Promises: an Introduction

【讨论】:

  • 非常感谢这个例子,很快就会试试这个。问题虽然我在Firebase 中有几个表,但我将在我的component.html 页面上根据这些表中的子项调用并再次返回数据并构建几个Dropdowns,但您提供的内容是从性能方面是否合适?或者我可以在这里使用 observable 吗? - 只是想更好地理解,因此愚蠢的问题o_O
  • 任何性能差异都取决于您如何构建事物。可观察对象的优点是它们可以继续发出值 - 因此它们可以连接到 child_added/removed 事件等,这可能涉及更少的数据传输和重复的、基于承诺的查询。我看到您正在使用 Angular,因此您可能需要查看 AngularFire2 以了解 observables 和 Firebase 的可能性。
  • 好吧听起来不错,我也看看 AngularFire2,刚刚尝试了您提供的 getExerciseOptions 方法,我收到以下错误:Type 'Promise' is not assignable to type '承诺'。 “Promise”类型中缺少属性“[Symbol.toStringTag]”。
  • 这只是 Firebase TypeScript 定义。为once 声明的承诺不使用泛型。你必须投射它:return this.exerciseDbRef2.once("value").then(...) as Promise&lt;Array&lt;Exercise&gt;&gt;;
猜你喜欢
  • 2021-07-03
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多