Angular 19 Firestore main.ts:5 ERROR NullInjectorError: R3InjectorError

Discussão em 'Angular' iniciado por casmaz, Janeiro 19, 2025.

  1. casmaz

    casmaz Guest

    main.ts:5 ERROR NullInjectorError: R3InjectorError(Standalone[_AppComponent])[Firestore3 -> Firestore3 -> InjectionToken angularfire2.firestore-instances -> [object Object] -> _NgZone -> _NgZone]: NullInjectorError: No provider for _NgZone!

    tried hundreds of combinations and i still get this error or similar. version is angular 19.

    main.ts

    import { bootstrapApplication } from '@angular/platform-browser';
    import { appConfig } from './app/app.config';
    import { AppComponent } from './app/app.component';

    bootstrapApplication(AppComponent, appConfig)
    .catch((err) => console.error(err));


    app.component.html

    <h1>Check-In App</h1>

    <mat-form-field appearance="fill">
    <mat-label>Select a member</mat-label>
    <input type="text" matInput [(ngModel)]="selectedMember" [matAutocomplete]="autoMembers" (input)="filterMembers()">
    <mat-autocomplete #autoMembers="matAutocomplete" [autoActiveFirstOption]="false">
    <mat-option *ngFor="let member of filteredMembers" [value]="member">
    {{ member }}
    </mat-option>
    </mat-autocomplete>
    </mat-form-field>
    <button (click)="addToParticipants()">Check In</button>

    <div>
    <h2>Checked-In Participants</h2>
    <ul>
    <li *ngFor="let participant of participants">
    {{ participant }}
    </li>
    </ul>
    </div>


    <mat-form-field appearance="fill">
    <mat-label>Select a participant</mat-label>
    <input type="text" matInput [(ngModel)]="selectedParticipant" [matAutocomplete]="autoParticipants" (input)="filterParticipants()">
    <mat-autocomplete #autoParticipants="matAutocomplete" [autoActiveFirstOption]="false">
    <mat-option *ngFor="let participant of filteredParticipants" [value]="participant">
    {{ participant }}
    </mat-option>
    </mat-autocomplete>
    </mat-form-field>
    <button (click)="removeFromParticipants()">Check Out</button>

    <div><button (click)="exportToExcel()">Export to Excel</button></div>


    app.config.ts

    import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
    import { provideRouter } from '@angular/router';

    import { routes } from './app.routes';
    import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
    import { getFirestore, provideFirestore } from '@angular/fire/firestore';

    export const appConfig: ApplicationConfig = {
    providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideFirebaseApp(() => initializeApp({"projectId":"","appId":"","storageBucket":"","apiKey":"","authDomain":"","messagingSenderId":"","measurementId":""})),
    provideFirestore(() => getFirestore())]
    };


    app.component.ts

    import { Component, OnInit, inject } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { NgFor } from '@angular/common';
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule, HttpClient } from '@angular/common/http';
    import { MatFormFieldModule } from '@angular/material/form-field'; // Import MatFormFieldModule
    import { MatSelectModule } from '@angular/material/select';
    import { MatAutocompleteModule } from '@angular/material/autocomplete'; // Import MatAutocompleteModule
    import { MatInputModule } from '@angular/material/input'; // Import MatInputModule
    import * as XLSX from 'xlsx';
    import { saveAs } from 'file-saver';
    import { Firestore, collection, collectionData, addDoc, getDocs } from '@angular/fire/firestore';
    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";
    import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/compat/firestore';
    import { Observable } from 'rxjs';
    import { environment } from '../environments/environment';


    interface Member {
    name: string;
    }



    initializeApp(environment);


    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    standalone: true,
    providers: [Firestore],
    imports: [NgFor, FormsModule, MatFormFieldModule, MatSelectModule, MatAutocompleteModule,
    MatInputModule, HttpClientModule
    ] // Include required modules
    })
    export class AppComponent implements OnInit {
    participants: string[] = [];
    members: string[] = [];
    filteredMembers: string[] = [];
    filteredParticipants: string[] = [];
    selectedMember: string = ''; // For check-in selection
    selectedParticipant: string = ''; // For check-out selection
    arr: Member[] = [];


    events$: Observable<any[]>;


    constructor(private http: HttpClient, private firestore: Firestore) {
    const aCollection = collection(this.firestore, 'items')
    this.events$ = collectionData(aCollection);
    }





    ngOnInit(): void {
    this.loadMembersFromCSV();
    //this.loadMembersFromFirestore(); // Load members from Firestore instead of CSV

    }



    exportToExcel(): void {
    const formattedData = this.filteredParticipants.map(participant => ({
    name: participant, // assuming 'name' is the field you want to show
    // You can include more fields if needed, e.g.
    // Age: participant.age,
    // Email: participant.email,
    }));
    console.log(formattedData)
    console.log(this.filteredParticipants)
    const worksheet = XLSX.utils.json_to_sheet(formattedData);
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Members');

    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
    saveAs(blob, 'members.xlsx');
    }

    filterMembers(): void {
    const query = this.selectedMember.toLowerCase();
    this.filteredMembers = this.members.filter(member =>
    member.toLowerCase().includes(query)
    );
    }

    filterParticipants(): void {
    const query = this.selectedParticipant.toLowerCase();
    this.filteredParticipants = this.participants.filter(participant =>
    participant.toLowerCase().includes(query)
    );
    }

    // Load members from the CSV file
    loadMembersFromCSV(): void {
    this.http.get('assets/members.csv', { responseType: 'text' }).subscribe({
    next: (data) => {
    //console.log(data)
    this.filteredMembers = this.members = data.split('\n').map(line => line.trim()).filter(line => line !== '');
    },
    error: (err) => {
    console.error('Error loading members from CSV:', err);
    }
    });
    }


    // Add selected member to participants
    addToParticipants(): void {
    if (this.selectedMember && !this.participants.includes(this.selectedMember)) {
    this.participants.push(this.selectedMember);
    }
    this.filterParticipants()
    this.selectedMember = '';
    }

    // Remove selected participant from participants
    removeFromParticipants(): void {
    if (this.selectedParticipant) {
    this.filteredParticipants = this.participants = this.participants.filter(participant => participant !== this.selectedParticipant);
    this.selectedParticipant = '';
    }
    }
    }


    app.module.ts

    // src/app/app.module.ts
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { CommonModule } from '@angular/common'; // Import CommonModule
    import { FormsModule } from '@angular/forms';
    import { HttpClientModule } from '@angular/common/http'; // Import HttpClientModule
    import { AppComponent } from './app.component';


    @NgModule({
    declarations: [

    ],
    imports: [
    BrowserModule,
    FormsModule,
    CommonModule // Add CommonModule here
    ],
    providers: [],
    bootstrap: []
    })
    export class AppModule { }


    environment.ts

    export const environment = {
    "projectId":"",
    "appId":"",
    "storageBucket":"",
    "apiKey":"",
    "authDomain":"",
    "messagingSenderId":"",
    "measurementId":""
    };

    Continue reading...

Compartilhe esta Página