I've been working on the Angular - Firebase tutorial from Google (https://developers.google.com/codelabs/building-a-web-app-with-angular-and-firebase) for several days, but I've encountered a persistent issue that I can't seem to resolve. Despite starting the tutorial from scratch three times to ensure I haven't missed any steps, the problem persists.
The main issue arises when I attempt to use the CdkDragDrop event in my app.component.html file. It consistently throws an error that reads:
Argument of type 'CdkDragDrop<Task[] | null, any, any>' is not assignable to parameter of type 'CdkDragDrop<Task[], Task[], any>'.ngtsc(2345)
app.component.ts(20, 7): Error occurs in the template of component AppComponent.
The error is displayed for drop($event)
in the following code snippet of app.component.html
:
<mat-card
cdkDropList
id="inProgress"
#inProgressList="cdkDropList"
[cdkDropListData]="inProgress | async"
[cdkDropListConnectedTo]="[todoList, doneList]"
(cdkDropListDropped)="drop($event)"
class="list">
<p class="empty-label" *ngIf="(inProgress | async)?.length === 0">Empty list</p>
<app-task (edit)="editTask('inProgress', $event)" *ngFor="let task of inProgress | async" cdkDrag [task]="task"></app-task>
</mat-card>
The drop
method in app.component.ts
looks like this:
drop(event: CdkDragDrop<Task[]>): void {
if (event.previousContainer === event.container) {
return;
}
const item = event.previousContainer.data[event.previousIndex];
this.store.firestore.runTransaction(() => {
const promise = Promise.all([
this.store.collection(event.previousContainer.id).doc(item.id).delete(),
this.store.collection(event.container.id).add(item),
]);
return promise;
});
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
This error has left me stuck and unable to progress further in the tutorial. I was able to successfully complete the tutorial each time up to this point, but from here on, nothing progresses because this error is displayed, and I simply can't find the source. I've spent a significant amount of time researching and troubleshooting, but I haven't been able to identify the root cause of the problem.
If anyone could provide assistance or guidance to help me resolve this issue, I would greatly appreciate it.
EDIT:
I have updated the method as per the recommendations in the comments. I am no longer encountering errors within my project. However, during the compilation process, I'm encountering an error message that indicates a type mismatch between the data types used in my project and the data types of the collections in my Firestore database. I don't understand how that can be. If you follow the tutorial correctly (which I most certainly did), then only string attributes are stored in the individual "Task" objects and I used all three collections as specified in the tutorial and stored them the same way in my Firestore. I don't understand how then a type mismatch can be present.
Below is the updated 'drop' method:
drop(event: CdkDragDrop<Task[] | null>): void {
if (event.previousContainer === event.container) {
return;
}
const item = event.previousContainer?.data?.[event.previousIndex];
if (!item) {
return;
}
this.store.firestore.runTransaction(() => {
const promise = Promise.all([
this.store.collection(event.previousContainer!.id).doc(item.id).delete(),
this.store.collection(event.container!.id).add(item),
]);
return promise;
});
transferArrayItem(
event.previousContainer!.data!,
event.container!.data!,
event.previousIndex,
event.currentIndex
);
}
The error message displayed in the terminal is as follows:
Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:18 - error TS2430: Interface 'DocumentSnapshotExists<T>' incorrectly extends interface 'DocumentSnapshot<DocumentData>'.
The types returned by 'data(...)' are incompatible between these types.
Type 'T' is not assignable to type 'DocumentData | undefined'.
Type 'T' is not assignable to type 'DocumentData'.
13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
~~~~~~~~~~~~~~~~~~~~~~
node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:41
13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
~
This type parameter might need an `extends firebase.firestore.DocumentData` constraint.
node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:41
13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
~
This type parameter might need an `extends firebase.firestore.DocumentData | undefined` constraint.
Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:23:18 - error TS2430: Interface 'QueryDocumentSnapshot<T>' incorrectly extends interface 'QueryDocumentSnapshot<DocumentData>'.
The types returned by 'data(...)' are incompatible between these types.
Type 'T' is not assignable to type 'DocumentData'.
23 export interface QueryDocumentSnapshot<T> extends firebase.firestore.QueryDocumentSnapshot {
~~~~~~~~~~~~~~~~~~~~~
node_modules/@angular/fire/compat/firestore/interfaces.d.ts:23:40
23 export interface QueryDocumentSnapshot<T> extends firebase.firestore.QueryDocumentSnapshot {
~
This type parameter might need an `extends firebase.firestore.DocumentData` constraint.
Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:26:18 - error TS2430: Interface 'QuerySnapshot<T>' incorrectly extends interface 'QuerySnapshot<DocumentData>'.
Types of property 'docs' are incompatible.
Type 'QueryDocumentSnapshot<T>[]' is not assignable to type 'QueryDocumentSnapshot<DocumentData>[]'.
Type 'QueryDocumentSnapshot<T>' is not assignable to type 'QueryDocumentSnapshot<DocumentData>'.
The types returned by 'data(...)' are incompatible between these types.
Type 'T' is not assignable to type 'DocumentData'.
26 export interface QuerySnapshot<T> extends firebase.firestore.QuerySnapshot {
~~~~~~~~~~~~~
node_modules/@angular/fire/compat/firestore/interfaces.d.ts:26:32
26 export interface QuerySnapshot<T> extends firebase.firestore.QuerySnapshot {
~
This type parameter might need an `extends firebase.firestore.DocumentData` constraint.
Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:29:18 - error TS2430: Interface 'DocumentChange<T>' incorrectly extends interface 'DocumentChange<DocumentData>'.
The types returned by 'doc.data(...)' are incompatible between these types.
Type 'T' is not assignable to type 'DocumentData'.
29 export interface DocumentChange<T> extends firebase.firestore.DocumentChange {
~~~~~~~~~~~~~~
node_modules/@angular/fire/compat/firestore/interfaces.d.ts:29:33
29 export interface DocumentChange<T> extends firebase.firestore.DocumentChange {
~
This type parameter might need an `extends firebase.firestore.DocumentData` constraint.
Error: node_modules/rxfire/firestore/lite/interfaces.d.ts:8:29 - error TS2314: Generic type 'AggregateQuerySnapshot<T>' requires 1 type argument(s).
8 export type CountSnapshot = lite.AggregateQuerySnapshot<{
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 count: lite.AggregateField<number>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 }, any, DocumentData>;
~~~~~~~~~~~~~~~~~~~~~
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
× Failed to compile.