控制台中的数组不为空,但array [0]未定义

时间:2019-12-26 11:57:52

标签: angular typescript ionic-framework google-cloud-firestore rxjs

在我的函数中,我从Firestore数据库中获取了数据。 我从表“ perturbations”中恢复数据,并从表“ trajetsFavorite”中恢复数据。 我想做的是从干扰集合中检索字段“ numero”并将其分配给数组“ numeroPertrubationsFavorite”,然后从集合“ trajetsFavorites”中恢复字段“ numero”并将其分配给数组“ numeroTrajetsFavorite”。 然后我读了我的2数组, 如果两个字段相等,则将变量“ isPerturbationsFavorite”设置为true。 我尝试了执行此操作的代码,当我创建console.log(this.numeroPerturbationsFavorite)时,数据很好地填充在数组中,对于console.log(this.numeroTrajetsFavorite)数据也显示得很好。 但是,当我执行console.log(this.numeroPerturbationsFavorites [0] .numero时,它是未定义的。 有谁能够帮助我?我认为可能是由于同步和异步引起的,但我不知道它是如何工作的。

我将我的代码放在这里:

  getPerturbationFavorite(){
        console.log(this.perturbationsBDD); //this is the variable to which i assign the data from the perturbation collection
        console.log(this.trajetFavorisBDD); //this is the variable to which i assign the data from the trajetFavorite collection

        this.numeroPerturbationsFavorite.length = 0;
        this.numeroTrajetFavorite.length = 0;
        this.perturbationsBDD.subscribe((res) => {
          console.log(res);
          for(let i = 0; i < res.length; i++){
            console.log('super' + res[i].numero);
            this.numeroPerturbationsFavorite.push({
              numero : res[i].numero
            });
          }
        })

        this.trajetFavorisBDD.subscribe((res) => {
          for(let i = 0; i < res.length; i++){
            console.log(res[i].numero);
            this.numeroTrajetFavorite.push({
              numero : res[i].numero
            });
          }
        })

        console.log(this.numeroPerturbationsFavorite); // display the data
        console.log(this.numeroTrajetFavorite); // display the data
        console.log(this.numeroTrajetFavorite[0].numero) //display undefined


      for(let i = 0; i < this.numeroPerturbationsFavorite.length; i++){
        console.log(this.numeroPerturbationsFavorite[i].numero); // dont display

        for(let a = 0; a < this.numeroTrajetFavorite.length; a++){
          console.log(this.numeroPerturbationsFavorite[i].numero); // dont display
          console.log(this.numeroTrajetFavorite[i].numero); // dont display
          if(this.numeroPerturbationsFavorite[i].numero === this.numeroTrajetFavorite[a].numero){

            this.isPerturbationsFavorite = true;
            console.log(this.isPerturbationsFavorite); // dont display
          }else{
            this.isPerturbationsFavorite = false;
            console.log(this.isPerturbationsFavorite); // dont display
          }
        }
      }
      }

this is the error

在这张照片中有一个错误,在错误的顶部有两个数组的结果

4 个答案:

答案 0 :(得分:0)

请控制台登录订阅块或启用异步功能

 this.trajetFavorisBDD.subscribe((res) => {
    for(let i = 0; i < res.length; i++){
        console.log(res[i].numero);
        this.numeroTrajetFavorite.push({
           numero : res[i].numero
        });
    }
    console.log(this.numeroTrajetFavorite); // display the data
    console.log(this.numeroTrajetFavorite[0].numero)
 })

答案 1 :(得分:0)

如果您声明res类型,可能对您有帮助

this.perturbationsBDD.subscribe((res: your_class_type[])

这将迫使您的代码知道响应是一个数组

无论如何,在提供服务时(我看到您还没有),您的函数必须返回一个可观察到的值:

perturbationsBDD() : Observable<your_class[]> {
 // body
} 

答案 2 :(得分:0)

您需要了解Java中异步调用的工作方式。

  1. 要使for loop工作,必须在异步调用完成后执行它, 这意味着它必须位于subscribe

  2. 的回调中
  3. 如果您尝试在subscribe之外循环,由于numeroPerturbationsFavorite.length在异步调用完成之前将始终为0,因此将使用no iterations执行for循环。

  4. 并且您看到console.log(this.numeroTrajetFavorite)中显示的数组的原因是,在异步完成后,当数组的值发生更改(或设置)时,浏览器会立即对其进行更新(如果:数组未展开,由用户在控制台中查看)

  5. 但是在console.log(this.numeroTrajetFavorite[0].numero)的情况下,浏览器不会更新(或打印)数组项,因为您试图在异步调用完成之前访问数组项。

建议:

subscribe内移动for循环,或创建一个单独的函数并从subscribe调用它

this.trajetFavorisBDD.subscribe(res => {
      for (let i = 0; i < res.length; i++) {
        console.log(res[i].numero);
        this.numeroTrajetFavorite.push({
          numero: res[i].numero
        });
      }
      this.myFunc()
});

myFunc() {
    console.log(this.numeroPerturbationsFavorite); // display the data
    console.log(this.numeroTrajetFavorite); // display the data
    console.log(this.numeroTrajetFavorite[0].numero); //display undefined

    for (let i = 0; i < this.numeroPerturbationsFavorite.length; i++) {
      console.log(this.numeroPerturbationsFavorite[i].numero); // dont display

      for (let a = 0; a < this.numeroTrajetFavorite.length; a++) {
        console.log(this.numeroPerturbationsFavorite[i].numero); // dont display
        console.log(this.numeroTrajetFavorite[i].numero); // dont display
        if (
          this.numeroPerturbationsFavorite[i].numero ===
          this.numeroTrajetFavorite[a].numero
        ) {
          this.isPerturbationsFavorite = true;
          console.log(this.isPerturbationsFavorite); // dont display
        } else {
          this.isPerturbationsFavorite = false;
          console.log(this.isPerturbationsFavorite); // dont display
        }
      }
    }
}

答案 3 :(得分:0)

由于您使用的是Angular,因此强烈建议您使用RxJS运算符,该运算符默认安装在Angular中。

在您的getPerturbationFavorite方法中,您将需要等待this.perturbationsBDDthis.trajetFavorisBDD的可观察值都完成,然后再执行其他任何相关操作。

为此,您可以使用combineLatest运算符,该运算符将从每个可观察对象中发出最后一个发出的值。这样,后续值将不会是undefined

import { combineLatest } from 'rxjs';

getPerturbationFavorite(){
  this.numeroPerturbationsFavorite.length = 0;
  this.numeroTrajetFavorite.length = 0;

  combineLatest(this.perturbationsBDD, this.trajetFavorisBDD).subscribe([res1, res2] => {
    for(let i = 0; i < res1.length; i++){
      this.numeroPerturbationsFavorite.push({
        numero : res1[i].numero
      });
    }

    for(let i = 0; i < res2.length; i++){
      this.numeroTrajetFavorite.push({
        numero : res2[i].numero
      });
    }

    for(let i = 0; i < this.numeroPerturbationsFavorite.length; i++){
      for(let a = 0; a < this.numeroTrajetFavorite.length; a++) {
        if(this.numeroPerturbationsFavorite[i].numero === this.numeroTrajetFavorite[a].numero) {
          this.isPerturbationsFavorite = true;
        } else {
          this.isPerturbationsFavorite = false;
        }
      }
    }
  });
}