CaglarCaliskan
CaglarCaliskan

Reputation: 105

Angular Firebase Get Data Sync

I want to get balance data from firebase. But it must be real-time.

I write the code below. The console output is "Balance: 0". After this output, it gets firebase data and writes it. So, before data come from firebase, the code continues and get balance function returns 0. I can't compare balance because of that. Actual data comes after that.

checkBalance() {
    let balance = this.authService.getBalance()
    result = this.authService.getBalance() >= this.price ? true : false
    console.log("Balance: " + balance);
    return result;
}

AuthService:

getBalance() {
    
    let docRef = this.angularFirestore.collection(`users`).doc(JSON.parse(localStorage.getItem('user')).uid);
    docRef.get().toPromise().then(function (doc) {
        if (doc.exists) {
            console.log(doc.data());
            console.log(doc.data().balance);
            return parseFloat(doc.data().balance);
        } else {
            // doc.data() will be undefined in this case
            console.log("Doc can not find!");
            return 0.0;
        }
    }).catch(function (error) {
        console.log("Error getting document:", error);
        return 0.0;
    });
    
    return 0.0;
}

Upvotes: 1

Views: 222

Answers (1)

Francesco Colamonici
Francesco Colamonici

Reputation: 1297

Original Answer

Steps

  1. Mark getBalance method async, and make it return your Promise
  2. Mark checkBalance method async
  3. Change the first line as follows: let balance = await this.authService.getBalance()

Sample

async getBalance() {
    const docRef = this.angularFirestore.collection(`users`).doc(JSON.parse(localStorage.getItem('user')).uid);

    return docRef.get().toPromise().then(function (doc) {
        if (doc.exists) {
            console.log(doc.data());
            console.log(doc.data().balance);
            return parseFloat(doc.data().balance);
        } else {
            // doc.data() will be undefined in this case
            console.log("Doc can not find!");
            return 0.0;
        }
    }).catch(function (error) {
        console.log("Error getting document:", error);
        return 0.0;
    });
}
async checkBalance() {
    const balance = await this.authService.getBalance();
    const result = balance >= this.price ? true : false;
    console.log("Balance: " + balance);

    return result;
}

JS Reference

Update For Angular 12 or Greater

Deprecation of toPromise in rxjs 7

Now instead of toPromise you have to use lastValueFrom or firstValueFrom from rxjs


import { firstValueFrom} from "rxjs";
async getBalance() {
    const docRef = this.angularFirestore.collection(`users`).doc(JSON.parse(localStorage.getItem('user')).uid);

    return firstValueFrom(docRef.get()).then(function (doc) {
        if (doc.exists) {
            console.log(doc.data());
            console.log(doc.data().balance);
            return parseFloat(doc.data().balance);
        } else {
            // doc.data() will be undefined in this case
            console.log("Doc can not find!");
            return 0.0;
        }
    }).catch(function (error) {
        console.log("Error getting document:", error);
        return 0.0;
    });
}

Rxjs Reference

Upvotes: 3

Related Questions