Infinite loop while checking existence of data


#1

Hi,

I am trying to add a logic in onChange() function where a record should get updated if it already else a new record should get inserted into firebase class.

Somehow my functions is always going to ELSE loop & it is getting executed infinite times. May be i have seen this code multiple times hence not able to drill down to the real issue. Can someone please help. Here is my code:

TS File:

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
import { UserData } from '../../../providers/user-data';
import { malesprofilePage } from '../../../pages/males/malesprofile/malesprofile';
import { AddmalePage } from '../../../pages/males/addmale/addmale';

/*
  Generated class for the maleslist page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
*/
@Component({
  selector: 'page-maleslist',
  templateUrl: 'maleslist.html'
})
export class maleslistPage {
  males: any;
  role: any;
  attendance: any;
  maleid: any;
  male: any;
  key: any;
  attendancedetails: FirebaseListObservable<any[]>;
  presentOn: FirebaseListObservable<any[]>;
  maleexists: any;


  constructor(public navCtrl: NavController, public navParams: NavParams, public userData: UserData, public af: AngularFire) {
    this.attendancedetails = this.af.database.list('/attendance/');
}

  onChange(attendance, male) {
    console.log(this.attendance);
    this.key = male.$key;
    console.log(this.key);
    this.presentOn = this.af.database.list('/attendance/' + this.key + '/presentOn');
    var newAttendance = {
      maleid: this.key,
      presentOn: [{
        attendance: this.attendance,
        date: firebase.database['ServerValue']['TIMESTAMP']
      }],
      schoolid: this.userData.schoolid
    }

    var presentOnUpdate = {
      attendance: this.attendance,
      date: firebase.database['ServerValue']['TIMESTAMP']
    }
    console.log(this.key);
  this.af.database.object('/attendance/'+this.key).subscribe((data) => {
  console.log(data);
  if (data.$exists()) {
    this.presentOn.push(presentOnUpdate).then(data => {
        //console.log(presentOnUpdate);
        console.log("If Loop");
      }, error => {
        console.log(error);
      });
    }
    else {
      this.attendancedetails.update(this.key, newAttendance).then(data => {
        console.log(newAttendance);
        console.log("Else Loop");
      }, error => {
        console.log(error);
      });
    }
    });
  
}

HTML File:

<!--
  Generated template for the maleslist page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>
    <ion-navbar>
        <ion-title>Males</ion-title>
    </ion-navbar>
</ion-header>
<ion-content padding>
    <ion-card *ngFor="let male of males | async" class="male">
        <input type="hidden" [(ngModel)]="male.$key" />
        <ion-list>   
            <ion-item (click)="goTomalesProfile(male)">
                <ion-avatar item-left>
                    <img [src]="male?.profilepic">
                </ion-avatar>
                    {{male?.fullname}}
            </ion-item>
            <ion-item>
                <ion-label>Attendance</ion-label>
      <ion-select [(ngModel)]="attendance" ionCancel="" (ionChange)="onChange(attendance.value, male)">
        <ion-option value="present">Present</ion-option>
        <ion-option value="absent">Absent</ion-option>
      </ion-select>
            </ion-item>
        </ion-list>  
    </ion-card>
    </div>
    <ion-card>
        <ion-list>   
            <ion-item (click)="goTomalesProfile(male)">
                <ion-avatar item-left>
                    <img [src]="male?.profilepic">
                </ion-avatar>
                    {{male?.fullname}}
            </ion-item>
            <!--<ion-item>
                <ion-label>Attendance</ion-label>
      <ion-select [(ngModel)]="attendance" ionCancel="" (ionChange)="onChange(attendance.value, male.$key)">
        <ion-option value="present">Present</ion-option>
        <ion-option value="absent">Absent</ion-option>
      </ion-select>
            </ion-item>-->
        </ion-list>  
    </ion-card>
    <ion-fab mini right bottom>
        <button ion-fab (click)=Addmale()>
            <ion-icon name="md-add-circle"></ion-icon>
        </button></ion-fab>
</ion-content>

#2

Can someone please have a look at above code?


#3

First thing I would do is systematically replace every instance of any in your code with a proper type. That often helps me uncover mistaken assumptions, and will definitely make it much easier for other people to understand your code.


#4

Sorry I didn’t get it. Are you saying that i should assign proper type to all the variables declared as any? What can be possible types? Most of my data is STRING.


#5

For example:

export class MalesListPage {
  males: string;
  role: string;
  attendance: string;
  maleid: number;
  male: string;
  key: number;
  attendancedetails: FirebaseListObservable<AttendanceDetails[]>;
  presentOn: FirebaseListObservable<string[]>;
  maleexists: boolean;
...

If you name the types correctly you can avoid undefined at runtime and already get compile-errors, which makes the development a lot easier.

What helped me:

  • Paste the json data from your backend at http://json2ts.com/ and get the models as ts interfaces like e.g. the AttendanceDetails I assumed.
  • Classes should be Upper-Case-Camel-Style => MalesListPage

#6

json2ts seems to be an interested option however i will have to understand this in little more detail. Can i use it to design my Firebase database or do we have any other option using which database can be designed?


#7

json2ts cannot be used for designing you database, only for generating your model interfaces in typescript to have type safety