I have a firestore collection called Collectors and I'm interacting with it via angularfire. I'm able to subscribe and filtered from it to get the documents on it especially the collectorBillNo (please refer to the image), however, I'm stuck on the part where I need to increment the value of the collectorBillNo by 1 and update the document when I call a savePayment function.
Service Component:
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
import {map } from 'rxjs/operators';
import { teller } from '../models/tellermodel';
export class CustomerService {
tellerCollections: AngularFirestoreCollection <teller>;
tellerDoc: AngularFirestoreDocument <teller>;
tellers: Observable<teller[]>;
constructor(
public angularFireStore: AngularFirestore
)
{}
getTeller() {
this.tellerCollections = this.angularFireStore.collection('collector');
this.tellers = this.tellerCollections.snapshotChanges().pipe(map(changes => {
return changes.map( a => {
const data = a.payload.doc.data() as teller;
data.id=a.payload.doc.id;
return data;
})
}))
return this.tellers
updateTeller( updateCol: teller) {
this.tellerDoc = this.angularFireStore.doc(`collector/${updateCol.id}`);
this.tellerDoc.update(updateCol);
}
}
HTML doing the filtering part
<div class="bill-heads">
<label>Teller Name: </label>
<select class="select-drop"
required
name="tellerName"
(change)="loadBilling($any($event.target).value)"
id="collector"
[(ngModel)]="updateLedger.collectorName">
<option
class ="teller-class"
value="{{tellerList.collectorName}}"
*ngFor ="let tellerList of tellerList"
>
{{tellerList.collectorName}}
</option>
</select>
</div>
Component ts
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { CustomerService } from 'src/app/services/customer.service'; // Service Component
import { teller } from 'src/app/models/tellermodel'; // Model
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-teller',
templateUrl: './teller.component.html',
styleUrls: ['./teller.component.scss']
})
export class TellerComponent implements OnInit {
constructor(
private customerService: CustomerService, // Calls the AngularFire Service
) { }
// Declarations goes Here
tellerList: teller[]; // loads the collection as observable
dataTellerSource: MatTableDataSource<any>; // for filtering
billNo: any; // this is where the collectorBillNo will be stored upon filtering
ngOnInit(): void {
//Subscribe to the collection
this.customerService.getTeller().subscribe(telObs => {
this.tellerList = telObs; // Subsribes as an Observable
this.dataTellerSource = new MatTableDataSource(telObs); // loads the observable as DataSource
})
loadBilling(collector:string) { // performs the filter from the HTML method
// using MatTableDatesource filter, I can able to filter the specific document,
get its collectorBillNo
this.collectorName = collector;
this.dataTellerSource.filter = collector.trim().toLowerCase();
this.billNo = this.dataTellerSource.filteredData
.map (bn => bn.collectorBillNo)
.reduce ((acc,cur) => acc+cur,0); // this gets the collectBillNo
savePayment() // it should update the document and increment the collectorCode by 1
this.billNo = this.billNo + 1
/// I don't know what to do next here for it to be able to save from its respective document
}
}
Bind the entire object to each option
in the HTML, using ngValue
. The selected object will be attached to the ngModel
variable of the select
element.
It seems you bound ngModel
to updateLedger.collectorName
which I don't see in the component, so I'll make a new variable called selectedTeller
.
<div class="bill-heads">
<label>Teller Name: </label>
<select class="select-drop"
required
name="tellerName"
id="collector"
[(ngModel)]="selectedTeller">
<option
class ="teller-class"
*ngFor ="let teller of tellerList"
[ngValue]="teller"
>
{{teller.collectorName}}
</option>
</select>
</div>
Notice I've removed the (change)
event, since angular will update the selected object automatically.
So your component will look like this
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { CustomerService } from 'src/app/services/customer.service'; // Service Component
import { teller } from 'src/app/models/tellermodel'; // Model
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-teller',
templateUrl: './teller.component.html',
styleUrls: ['./teller.component.scss']
})
export class TellerComponent implements OnInit {
constructor(
private customerService: CustomerService, // Calls the AngularFire Service
) { }
// Declarations goes Here
tellerList: teller[]; // loads the collection as observable
dataTellerSource: MatTableDataSource<any>; // for filtering
billNo: any; // this is where the collectorBillNo will be stored upon filtering
selectedTeller: teller;
ngOnInit(): void {
//Subscribe to the collection
this.customerService.getTeller().subscribe(telObs => {
this.tellerList = telObs; // Subsribes as an Observable
this.dataTellerSource = new MatTableDataSource(telObs); // loads the observable as DataSource
})
savePayment() {
this.customerService.updateTeller({ ...this.selectedTeller, collectorBillNo: this.selectedTeller.collectorBillNo + 1 });
}
}