FirebaseExtended / angularfire

AngularJS bindings for Firebase
MIT License
2.73k stars 632 forks source link

Can't read uid outside this.afAuth.authState.subscribe() method, it says uid undefined after I reload the page #969

Closed mohamedelbalshy closed 4 years ago

mohamedelbalshy commented 6 years ago

Here is My Product.Service which uid is undefined after i reloading the Page, but it's defined after i login in the first time, i don't know why, Please can anyone help me to discover this problem, i searched but i didn't found a solution and i asked many people but no one answer me, i'm new to Angular

 import { Injectable, EventEmitter, Output } from "@angular/core";
        import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database-deprecated';
        import * as firebase from 'firebase/app';
        import { AngularFireAuth } from 'angularfire2/auth';

        import { Product } from "./models/product.model";
        import { METHODS } from "http";

    @Injectable()
    export class ProductService{

        products: FirebaseListObservable<Product[]>;
        user : firebase.User;
        users : Array<any> = [];
        final_data: Array<any> = [];
        uid:string;

        constructor(
            private db: AngularFireDatabase,
            private afAuth: AngularFireAuth
            ) {
                this.afAuth.authState.subscribe(auth => {
                  if (auth !== undefined && auth !== null) {
                    this.user = auth;

                    console.log(this.user.uid);// uid is defined here
                  }
                });

                console.log(this.user.uid);// uid is undefined here

            }

           getProducts(): FirebaseListObservable<Product[]>{

                return this.db.list(`users/${this.user.uid}/products`);
           }

Here is my Component which displays Products:

import { Component, OnInit, Input, AfterViewChecked, OnChanges } from '@angular/core';
import { Product } from '../models/product.model';
import { ProductService } from '../product.service';
import { ShoppingCartService } from './shopping-cart.service';
import { AuthServiceService } from '../auth-service.service';
import { FirebaseListObservable } from 'angularfire2/database-deprecated';
import { AngularFireAuth } from 'angularfire2/auth';

@Component({
  selector: 'app-shopping-cart',
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.css']
})
export class ShoppingCartComponent implements OnInit, OnChanges {

  products:FirebaseListObservable<Product[]>;
  productsArray : Product[];
  sum:number = 0;

  constructor( private ProdService: ProductService, private afAuth: AngularFireAuth) {

   }

  ngOnInit() {
    this.afAuth.authState.subscribe(
      auth => console.log(auth.uid, " Shopping Cart") // uid is defined
    )

    this.products = this.ProdService.getProducts(); // uid is undefined here

  }
  ngOnChanges(){
    this.products = this.ProdService.getProducts(); // uid is undefined here

  }

}
davidheis commented 6 years ago

im new too, but i think its because the code in this.afAuth.authState.subscribe is taking time before it finishes, but in the meantime the javascript has been executed outside that scope while uid has never been assiged any value

calledtoconstruct commented 6 years ago

You should consider using rxjs. Create a subject for the user identity, then use the subject.next(user.uid) to publish the value to subscribers who need it. The alternative is to move the call to getProducts inside the subscribe callback.