1

My login component logs the user in successfully, but then I'd like to create a document for this user in FireStore.

I keep getting an issue loading the AngularFirestore afs in this case.

zone-evergreen.js:659 Unhandled Promise rejection: Cannot read property 'afs' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'afs' of undefined
    at onLoginFulfiled (login.component.ts:32)
    at ZoneDelegate.invoke (zone-evergreen.js:365)
    at Zone.run (zone-evergreen.js:124)
    at zone-evergreen.js:851
    at ZoneDelegate.invokeTask (zone-evergreen.js:400)

Here is my login component code.

import { Component, OnInit } from '@angular/core';
import { LoginRequest } from './loginRequest';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { auth } from 'firebase/app';
import 'firebase/firestore';

export interface Item { uid: string; }

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

  loginRequest: LoginRequest = { password: '', login: ''};
  constructor(public fireAuth: AngularFireAuth, public afs: AngularFirestore) { }

  ngOnInit(): void {
  }

  login(): void {
    console.log(this.loginRequest);
    this.fireAuth.signInWithEmailAndPassword(this.loginRequest.login, this.loginRequest.password)
      .then(this.onLoginFulfiled, this.onLoginRejected);
  }

  onLoginFulfiled(credential: auth.UserCredential): void {
    console.log('Fulfilled: ' + credential);
    const uid = credential.user.uid;
    const userDocument = this.afs.doc<Item>(`system-users/${uid}`);
    userDocument.update({uid});
  }

  onLoginRejected(reason: any): void {
    console.log('Rejected: ' + reason);
  }
}

Also my app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { AngularFireModule } from '@angular/fire';
import { AngularFireAnalyticsModule } from '@angular/fire/analytics';
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { environment } from '../environments/environment';
import { LoginComponent } from './login/login.component';

@NgModule({
  declarations: [
    AppComponent,
    PageNotFoundComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAnalyticsModule,
    AngularFirestoreModule,
    AppRoutingModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Evan Anger
  • 712
  • 1
  • 5
  • 24

1 Answers1

1

Try replacing

.then(this.onLoginFulfiled, this.onLoginRejected);

with

.then(() => this.onLoginFulfiled(), () => this.onLoginRejected());
Stratubas
  • 2,939
  • 1
  • 13
  • 18
  • Ugh - crazy this worked. Can you help me understand why this worked!? I'm newer to angular, also I'd like to update question to be more exact. – Evan Anger Mar 16 '20 at 15:58
  • login(): void { this.fireAuth.signInWithEmailAndPassword(this.loginRequest.login, this.loginRequest.password) .then( (credential) => this.onLoginFulfiled(credential), (reason: any) => this.onLoginRejected(reason) ); } – Evan Anger Mar 16 '20 at 15:59
  • Here's how it looked exactly, I ran into a different issue, but one with my firestore setup which can work through now. – Evan Anger Mar 16 '20 at 16:00
  • @EvanAnger I don't think this is Angular-related. It's about how `this` works in functions. With `=>`, the `this` is your `LoginComponent`, which has the `afs` property. See this question https://stackoverflow.com/q/24900875/6002078 – Stratubas Mar 16 '20 at 16:06
  • @EvanAnger an alternative would be `this.onLoginFulfiled.bind(this)`, which makes the `this` inside the function to be the `this` from the context you use `bind()` at (which is the `LoginComponent`. – Stratubas Mar 16 '20 at 16:07
  • 1
    OK - I should have said... I'm new not just to Angular but JS/TS/etc. haha. Thanks for the link and suggestion. I'm back rolling on this fun journey here. – Evan Anger Mar 16 '20 at 16:08