简体   繁体   中英

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[NavbarComponent -> NavbarComponent

I am trying to make a login with google Auth on Firebase and when I login and try to load another component or a page I get the following. I have been trying to fix this bug for a whole day now and am very fed up. If anyone could help it would be appreciated.

My entire project is public at https://github.com/domilx/ProjetBocal-Angular

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[NavbarComponent -> NavbarComponent -> NavbarComponent]: 
  NullInjectorError: No provider for NavbarComponent!
get@http://localhost:4200/vendor.js:120414:27

Here is my code

Navbar.component.html:

<div mat-elevation-z4>
  <mat-toolbar color="primary">
    <button routerLink="dashboard" mat-button aria-label="Home">
      <mat-icon>home</mat-icon>
      Projet Bocal
    </button>

    <span class="spacer-1"></span>

    <button mat-button aria-label="Classroom">
      <mat-icon>class</mat-icon>
      Classroom
    </button>

    <button mat-button aria-label="Links">
      <mat-icon>links</mat-icon>
      Links
    </button>

    <span class="spacer-1"></span>

    <button mat-button aria-label="Logout" *ngIf="auth.user$ | async as user" (click)="auth.signOut()">
      <mat-icon>exit_to_app</mat-icon>
      Logout, {{ user.displayName }}
    </button>
    <span class="spacer"></span>

    <button routerLink="settings" mat-icon-button aria-label="settings" *ngIf="auth.user$ | async as user">
      <mat-icon>settings</mat-icon>
    </button>

  </mat-toolbar>
</div>

Auth.service.ts

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
import { Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { User } from './user.model';
import { AngularFireAuth }  from '@angular/fire/compat/auth';
import { GoogleAuthProvider } from 'firebase/auth';

@Injectable({ providedIn: 'root' })
export class AuthService {
  user$: Observable<User | null | undefined>;
  constructor(
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router,
  ) {
    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
        } else {
          return of(null);
        }
      })
    );
  }

  async googleSignin() {
    const provider = new GoogleAuthProvider();
    const credential = await this.afAuth.signInWithPopup(provider);
    return this.updateUserData(credential.user);
  }

  async signOut() {
    await this.afAuth.signOut();
    return this.router.navigate(['/']);
  }

  private updateUserData(user) {
    // Sets user data to firestore on login
    const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);

    const data = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL
    };

    return userRef.set(data, { merge: true });

  }
}

Auth.guard.ts

import { Injectable } from '@angular/core';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  Router
} from '@angular/router';
import { Observable } from 'rxjs';

import { AuthService } from './auth.service';
import { tap, map, take } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthService, private router: Router) {}

  canActivate(next, state): Observable<boolean> {
    return this.auth.user$.pipe(
      take(1),
      map(user => !!user), // <-- map to boolean
      tap(loggedIn => {
        if (!loggedIn) {
          console.log('access denied');
          this.router.navigate(['/']);
        }
      })
    );
  }
}

App.module.ts

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore/';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './components/pages/about/about.component';
import { ContactComponent } from './components/pages/contact/contact.component';
import { ClassroomComponent } from './components/pages/dashboard/classroom/classroom.component';
import { DashboardComponent } from './components/pages/dashboard/dashboard/dashboard.component';
import { LinksComponent } from './components/pages/dashboard/links/links.component';
import { HomeComponent } from './components/pages/home/home.component';
import { SettingsComponent } from './components/pages/settings/settings.component';
import { FooterComponent } from './components/shared/footer/footer.component';
import { NavbarComponent } from './components/shared/navbar/navbar.component';
import { MaterialModule } from './material.module';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './services/auth.guard';


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    FooterComponent,
    AboutComponent,
    SettingsComponent,
    ContactComponent,
    DashboardComponent,
    HomeComponent,
    ClassroomComponent,
    LinksComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    RouterModule,
    MaterialModule,
    FormsModule,
    ReactiveFormsModule,
    HttpClientModule,
    AngularFireAuthModule,
    AngularFirestoreModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireDatabaseModule,
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideFirestore(() => getFirestore()),
    provideAuth(() => getAuth()),

  ],
  providers: [
    AngularFirestoreModule,
    AngularFireModule,
    AngularFireAuthModule,
    AngularFireDatabaseModule,
    AuthGuard,
    AuthService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

App-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SettingsComponent } from './components/pages/settings/settings.component';
import { AboutComponent} from './components/pages/about/about.component';
import { ContactComponent} from './components/pages/contact/contact.component';
import { DashboardComponent } from './components/pages/dashboard/dashboard/dashboard.component';
import { HomeComponent } from './components/pages/home/home.component';
import { AuthGuard } from './services/auth.guard';

const routes: Routes = [
  {path:'', component:HomeComponent},
  {path:'settings', component:SettingsComponent,  canActivate: [AuthGuard] },
  {path:'home', redirectTo:'/', pathMatch:'full'},
  {path:'about', component:AboutComponent,  canActivate: [AuthGuard] },
  {path:'contact', component:ContactComponent,  canActivate: [AuthGuard] },
  {path:'dashboard', component:DashboardComponent,  canActivate: [AuthGuard] },
];
  @NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
  })
export class AppRoutingModule { }

navbar.component.ts

import { Component, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AuthService } from '../../../services/auth.service';

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

  constructor(public auth: AuthService) { }
  ngOnInit(): void {
  }

}

I found the issue.. In my dashboard.component.ts I had imported the NavBar for test a long while ago and forgot to remove it:

import { NavbarComponent } from './../../../shared/navbar/navbar.component';
import { Component, OnInit,EventEmitter,Output } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AuthService } from '../../../../services/auth.service';

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

  @Output() isLogout = new EventEmitter<void>()
  constructor(NavbarComponent : NavbarComponent, public auth: AuthService) { }


  ngOnInit(): void {

  }

}

Just had to remove

NavbarComponent : NavbarComponent

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM