I'm following the AngularFire Quickstart tutorial. I got Read working, which displays the data from my Firestore database in the Angular view. I'm stumped how to get Create (set
) working.
My app.component.html
displays a little text form field with a Submit
button, and the displays the values in the Firestore database:
<form (ngSubmit)="onSubmit()">
<input type="text" [(ngModel)]="name" name="name">
<button type="submit" value="Submit" >Submit</button>
</form>
<ul>
<li class="text" *ngFor="let item of items | async">
{{item.name}}
</li>
</ul>
My app.component.ts
file has a function onSubmit()
that executes when the user clicks the Submit
button. It logs the name that the user entered in the text form field. The next line throws this error:
TS2339: Property 'firestore' does not exist on type 'AppComponent'.
23 this.firestore.collection('items').doc('item').set({name: this.name}); // error is here
Here's my app.component.ts
:
import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
items: Observable<any[]>;
constructor(firestore: AngularFirestore) {
this.items = firestore.collection('items').valueChanges();
}
name: string | null = null;
onSubmit() {
console.log(this.name);
this.firestore.collection('items').doc('item').set({name: this.name}); // error is here
return // return what?
}
}
This is the same pattern as the Tour of Heroes tutorial:
export class HeroService {
constructor(private logger: Logger) { }
getHeroes() {
this.logger.log('Getting heroes ...');
return HEROES;
}
}
My app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
// Firebase
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { environment } from '../environments/environment';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
AngularFireModule.initializeApp(environment.firebase),
AngularFirestoreModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
The view:
And my Firestore database:
I think the issue here is related to TypeScript. I believe best-practice, in this case, would be for you to use the private
access modifier in front of firestore: Firestore
while injecting it into the constructor of the component or service where you are using it, in your case app.component.ts.
The private
access modifier does a couple things:
firestore: any;
)constructor(private firestore: AngularFirestore) {
this.items = firestore.collection('items').valueChanges();
}