为什么我的代码不运行,即使它在一个函数中并且上面的pring语句也起作用?

问题描述 投票:0回答:1

我正在运行一个有角度的项目,该文件将从Firebase数据库中获取数据,而getStatistics()函数底部的代码将使用不同访问数据对的信息填充map(pairArray),数据库包含。

问题是,getStatistics()函数底部的代码(由反斜杠表示)将无法运行。好吧,在for或if-else循环中什么都不会运行。虽然console.log()函数可以工作,所以我不确定为什么代码无法运行。如果我将它放在函数中的较高位置,它将在所有计算百分比的数学下运行。

import { Component, OnInit } from '@angular/core';

// Firestore imports 
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
import {Observable,of, from, Timestamp } from 'rxjs';
//import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import * as firebase from 'firebase';
import { NgForm, NgModel } from '@angular/forms';

/*
 getStatistics function:

The goal of this function is to iterate through the database and get the required statistics.
The structure of the database:
  visits IDs are stored as collections, files, in the firestore database.
  Visits of the same ID are stored as documents inside each collection.
The function iterates through each collection, ID,  and counts how many visits are stored in each ID,
 then it increments the AgencyCounter for each agency that was detected in the collection.
The iteration over collections and documents in the database is done by using the "payload.forEach" method

TODO
1. Identify group visits and exclude them from the getStatistics()
2. correct the common pair and common triplet algorithm. Agencies should be sorted based on how many times 
   they appreared in the pair or triplet visits.

 */

interface  Visit{
  code: number;
}

// interface that defines the agency visit structure
interface  AencyVisit{
  AgencyID: string;
  code: string;
  time: Timestamp<any>;
}


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

   // Connect Agency to Firebase collection
   visitCollection: AngularFirestoreCollection<Visit>;
   visits: Observable<Visit[]>;

   // Statistics fields
  totalNumVisits = 0;
  totalMultipleVisits = 0;
  highest = 0;
   totalNumPairVisits = 0 ;
   percentageOfPairVisits = 0;
   totalNumTripletVisits = 0;
    percentageOfTripletVisits = 0;
  totalNum5PlusVisits = 0;
  lastHighest = 0;
  percentageOf5PlusVisits = 0;
  totalNum4Visits = 0;
  percentageOf4Visits = 0;
  keyHolder = "";
  valueAdjuster = 0;
  timer = null;
  k = 0;
   commonPairs = new Array();
   commonPair = new Array();
   commonTriplets = new Array();
   commonTriplet = new Array();
   values = new Array();
   //this.values.push(rand = new Array());
   //visitsy = new Array<Observable<Visit[]>>();

   agencyCounterPerID=0;
  //  counterArray ={1:0, 2:0 , 3:0}; //  key represents duplicate or triplet of agencies, value = their number
   // 32 max agency limit per visit - hopefully no one should ever reach this
   counterArray = [0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   
   //pairArray = new Map<Array<Object>, number>(); 
   pairArray = new Map<string, number>(); 
   multiples = 0;
   //  mostCommonPairList and mostCommonTripletList will be used to filter the most common pair and triplet agencies
   mostCommonPairList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
   mostCommonTripletList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
   agencyList = new Array(); 
   IDField: Observable<any>;

   // Percentage calculations
   pctMultipleAgencyVisits: number;

  constructor(private afs: AngularFirestore) { }

  ngOnInit(): void {
    // console.log("a");
    this.getStatistics();
  }

  getStatistics(): void{
    const visitArray = this.afs.collection("visits").snapshotChanges();

    visitArray.subscribe(payload => {
      this.totalNumVisits = 0;
      this.totalNumPairVisits = 0;
      this.percentageOfPairVisits = 0;
      this.totalNumTripletVisits = 0;
      this.percentageOfTripletVisits = 0;
      this.totalNum5PlusVisits = 0;
      this.percentageOf5PlusVisits = 0;
      this.totalNum4Visits = 0;
      this.percentageOf4Visits = 0;
      const values = [];



      payload.forEach( item => {
        const visit = item.payload.doc.data() as Visit;
        //const values = [];
        this.totalNumVisits += 1;
        this.timer = null;

        // getting visited frequencies
        const visitedAgencies = this.afs.collection(visit.code.toString()).snapshotChanges();
        visitedAgencies.subscribe(payload => {


          this.agencyCounterPerID = payload.length;
          this.k = 0;
          payload.forEach( item => {
            const agencyVisit = item.payload.doc.data() as AencyVisit; 
            this.agencyList.push(agencyVisit.AgencyID);

            // Add visit pairs to nested list for later analysis
            if (this.agencyCounterPerID == 2){
                if (this.k == 0){
                    this.values.push(new Array(agencyVisit.AgencyID.toString()));
                }

                if (this.k == 1){
                    this.values[this.values.length - 1].push(agencyVisit.AgencyID.toString());
                }

                this.k = 1;
            }
          });

          console.log("list", this.agencyList.toString());

          this.counterArray[this.agencyCounterPerID]+=1;
          if (this.agencyCounterPerID == 2) {
            this.totalNumPairVisits += 1;
            var result2 = this.agencyList.includes(this.agencyList[i]);
            this.mostCommonPairList[this.agencyList[i]] += 1;
          } else if (this.agencyCounterPerID == 3) {
            this.totalNumTripletVisits += 1;
            var result3 = this.agencyList.includes(this.agencyList[i]);
            this.mostCommonTripletList[this.agencyList[i]] += 1;
          } else if (this.agencyCounterPerID == 4) {
            this.totalNum4Visits += 1;
          } else if (this.agencyCounterPerID >= 5) {
            this.totalNum5PlusVisits += 1;
          }

          for (var i=2; i<this.counterArray.length; i++) {
           this.multiples+= this.counterArray[i];
          }

          // percentages
          this.pctMultipleAgencyVisits = this.totalNumVisits / this.counterArray[2];//this.multiples;
          this.totalMultipleVisits = this.totalNumPairVisits + this.totalNumTripletVisits + this.totalNum4Visits + this.totalNum5PlusVisits;
          this.percentageOfPairVisits = this.totalNumPairVisits / this.totalMultipleVisits * 100 ;
          this.percentageOfTripletVisits = this.totalNumTripletVisits / this.totalMultipleVisits * 100;
          this.percentageOf4Visits = this.totalNum4Visits / this.totalMultipleVisits * 100;
          this.percentageOf5PlusVisits = this.totalNum5PlusVisits / this.totalMultipleVisits * 100;
          this.commonPair.push(this.agencyList[0]);
          this.commonPair.push(this.agencyList[1]);
          this.commonTriplet.push(this.agencyList[0]);
          this.commonTriplet.push(this.agencyList[0]);

          this.agencyCounterPerID =0;
          //empty the array
          this.agencyList.length = 0;

        });

    });

  });

    console.log("working");

    /////////////////////////////////////////////////////////////////////////////
    //format pairs into sorted strings
    for (let u = 0; u < this.values.length; u++){
        this.values[u].sort();
        this.values[u].toString();
        console.log("here1");
    }

    //add values to map(dictionary)
    for (let p = 0; p < this.values.length; p++){
        if (this.pairArray.has(this.values[p].toString()) == false){
            this.pairArray.set(this.values[p].toString(), 1);
            console.log("here2");
        }
        else if (this.pairArray.has(this.values[p].toString()) == true){
            //return this.pairArray;
            for (let a = 0; a < 10000; a++){
                if (this.pairArray.get(this.values[p].toString()) == a){
                    this.keyHolder = this.values[p].toString();
                    this.valueAdjuster = a + 1;

                    this.pairArray.delete(this.values[p].toString());
                    console.log("here3");
                }
                console.log("here4");
            }
            this.pairArray.set(this.keyHolder, this.valueAdjuster);
            console.log("here5");
        }
    }

    //find number of occurences of highest frequency pair
    this.highest = 0;
    for (let [key, value] of this.pairArray) {
        console.log("here7");
        if (value > this.highest){
            this.highest = value;
            console.log("here6");
        }
    }

    //add highest frequency pair to list
    for (let [key, value] of this.pairArray) {
        console.log("here9");
        if (value == this.highest && this.commonPairs.indexOf(key) == -1){
            this.commonPairs.push(key);
            console.log("here8");
            //break;
        }
    }

    //find number of occurences of second highest frequency pair
    this.lastHighest = this.highest;
    this.highest = 0;
    for (let [key, value] of this.pairArray) {
        console.log("here11");
        if (value > this.highest && value != this.lastHighest){
            this.highest = value;
            console.log("here10");
        }
    }

    //add second highest frequency pair to list
    for (let [key, value] of this.pairArray) {
        console.log("here13");
        if (value == this.highest && this.commonPairs.indexOf(key) == -1){
            this.commonPairs.push(key);
            console.log("here12");
        }
    }

    // Prints out the dictionary
    for (let [key, value] of this.pairArray) {
        console.log("here14");
        console.log("key: ", key.toString(), ", value: ", value);
    }
    console.log("end run");

    /////////////////////////////////////////////////////////////////////////////

  //console.log("values", this.values);

  // console.log(this.counterArray[1] , " visit for " , 1 , "agencies");
  // console.log(this.counterArray[2] , " visit for " , 2 , "agencies");
  // console.log(this.counterArray[3] , " visit for " , 3 , "agencies");

    //console.log("len", this.values.length);

    //console.log("counter: ", this.counterArray);



    //console.log("cp: ", typeof(this.commonPairs[0]));
    //console.log("v: ", typeof(this.values[0]));
    //console.log("values: ", this.values);

  }

  formatPercent(num) {
    return Math.round(num * 100) / 100;
  }
}
angular typescript firebase loops google-cloud-firestore
1个回答
0
投票

嗯,您的代码很多,但是看起来底部的for循环正在订阅外部调用。由于这是异步代码,因此在函数运行时,for循环中的值未定义或为空,因为尚未从firebase调用中获取值。当您调用订阅时,代码执行继续进行,同时第二个线程等待响应以执行订阅中的代码。

© www.soinside.com 2019 - 2024. All rights reserved.