Oleksandr Tatarinov
Oleksandr Tatarinov

Reputation: 323

Why i get error with Interfaces and Observable?

I build ToDoApp and connect firebase to my project but i have error.

ERROR in src/app/todo-component/todo-component.component.ts(25,7): error TS2740: Type 'DocumentChangeAction<{}>[]' is missing the following properties from type 'Observable<ToDoInterface[]>': _isScalar, source, operator, lift, and 5 more.

Here my ToDOInterface:

export interface  ToDoInterface {
  id?: string;
  title?: string;
  completed?: boolean;
}

My ToDoService:

import { Injectable } from '@angular/core';
import {ToDoInterface} from './ToDoInterface'
import {AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from "@angular/fire/firestore";
import {Observable} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class ToDoService {
  public toDoArray:ToDoInterface[] = [
    {
      id: "sdfsdf",
      title: 'Todo one',
      completed: false
    },
    {
      id: "13dsfsdf",
      title: 'Todo two',
      completed: false
    },
    {
      id: "safsdf",
      title: 'Todo third',
      completed: false
    }
  ];
  ToDoCollection: AngularFirestoreCollection<ToDoInterface>;
  ToDo: Observable<ToDoInterface[]>;
  ToDoCollectionName: string = "ToDo";
  constructor(private firestore: AngularFirestore) {

  }
  getToDos(){
    return this.toDoArray;
  }
  getToDosFirebase(){
    return this.firestore.collection(this.ToDoCollectionName).snapshotChanges();
  }
  changeToDos(index,property,value){
    this.toDoArray[index][property] = value;
  }
  deleteToDos(index){
    this.toDoArray.splice(index,1);
  }
  deleteToDosFirebase(index){
    // this.firestore.collection("ToDO").doc(index).delete();
  }
  addToDos(obj: ToDoInterface){
    this.toDoArray.push(obj);
  }
  addToDosFirebase(obj: ToDoInterface){
    return new Promise<any>(((resolve, reject) => {
      this.firestore
        .collection("ToDo")
        .add(obj)
        .then(res => console.log('data send!'), err => reject(err))
    }))
  }
}

And my function what i call in ngOnInit

getToDo(){
    this._toDoService.getToDosFirebase().subscribe(items => {
      this.toDosFirebase = items;
      console.log(items);
    });

Maybe i dont know some about rxjs but here data from that func if toDosFirebase: Observable<any[]>; and how i can see it normal for my Interface

enter image description here

In service i hardcode data and all works fine, and my hardcoded data by types equal data from firebase.

Do like in official documentation:

private ToDoCollection: AngularFirestoreCollection<ToDoInterface>;
  ToDo: Observable<ToDoIdInterface[]>;
  ToDoCollectionName: string = "ToDo";
  constructor(private readonly firestore: AngularFirestore) {
    this.ToDoCollection = firestore.collection<ToDoInterface>(this.ToDoCollectionName);
    this.ToDo = this.ToDoCollection.snapshotChanges().pipe(
      map(a => {
        const data = a.payload.doc.data() as ToDoInterface; //ERROR
        const id = a.payload.doc.id;
        return {id, ...data}
        }
      ));
    console.log(this.ToDo);
  }

Upvotes: 0

Views: 298

Answers (1)

robert
robert

Reputation: 6152

In your "getToDosFirebase" method you are calling a ".snapshotChanges();" method.

Actions returned by snapshotChanges are of type DocumentChangeAction and contain a type and a payload. The type is either added, modified or removed and the payload contains the document's id, metadata and data.

In other words you need to map the received data something like this:

.snapshotChanges()
.map(actions => {
   return actions.map(a => {

     //Get document data
     const data = a.payload.doc.data() as Task;

     //Get document id
     const id = a.payload.doc.id;

     //Use spread operator to add the id to the document data
     return { id, …data };
   });
});

For more information see these links: link1, link2

update

In your "to-do-service.service.ts"

change this line:

ToDo: Observable<ToDoIdInterface[]>;

to this:

ToDo: Observable<any>;

also change this:

map(a => {

to this:

map((a: any) => {

After this the project should build correctly.

Upvotes: 1

Related Questions