Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why am I obtaining this "'id' is specified more than once…" error trying to spread out id and data() from the result returned by Firestore?

it is passed a lot of time from the last time that I worked on Angular and Firebase and I am finding the following simple problem trying to use AngularFire 2 in order to retrieve the entire objects from a Firestore collection (it means the document ID + the document data that must be put into a model object).

So this is my situation.

First of all this is my package.json file:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
  "name": "fintness-tracker",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~13.3.0",
    "@angular/cdk": "^13.3.8",
    "@angular/common": "~13.3.0",
    "@angular/compiler": "~13.3.0",
    "@angular/core": "~13.3.0",
    "@angular/flex-layout": "^13.0.0-beta.38",
    "@angular/forms": "~13.3.0",
    "@angular/material": "^13.3.8",
    "@angular/platform-browser": "~13.3.0",
    "@angular/platform-browser-dynamic": "~13.3.0",
    "@angular/router": "~13.3.0",
    "angularfire2": "^5.4.2",
    "firebase": "^7.24.0",
    "hammerjs": "^2.0.8",
    "rxjs": "~7.5.0",
    "rxjs-compat": "^6.6.7",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.3.6",
    "@angular/cli": "~13.3.6",
    "@angular/compiler-cli": "~13.3.0",
    "@types/jasmine": "~3.10.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~4.0.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.1.0",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.6.2"
  }
}

Then I have this simple Exercise model interface that will map a Firebase document:

export interface Exercise {
    id: string;
    name: string;
    duration: number;
    calories: number;
    date?: Date;
    state?: 'completed' | 'cancelled' | null;
}

And finally my NewTrainingComponent Angular component class, in its ngOnInit()

import { Component, OnInit, EventEmitter, Output } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Exercise } from '../exercise.model';
import { TrainingService } from '../training.service';
import { AngularFirestore } from 'angularfire2/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';



@Component({
  selector: 'app-new-training',
  templateUrl: './new-training.component.html',
  styleUrls: ['./new-training.component.css']
})
export class NewTrainingComponent implements OnInit {

  @Output()
  trainingStart:EventEmitter<void> = new EventEmitter<void>();

  //exercises: Exercise[] = [];
  exercises: Observable<any>;

  constructor(private trainingService: TrainingService,
              private db: AngularFirestore) { }

  ngOnInit(): void {
    //this.exercises = this.trainingService.getAvailableExercises();

    //this.exercises = this.db
    this.db
      .collection("availableExercises")
      .snapshotChanges()
      .pipe(
        map((docArray) => {
          return docArray.map((doc) => {
            return {
              id: doc.payload.doc.id,
              ...(doc.payload.doc.data() as Exercise),
            };
          });
        })
      )
      .subscribe(result => {
        console.log(result);

      });

    /*
    this.db.collection('availableExercises').valueChanges().subscribe(result => {
      console.log(result);
    })
    */
  }

  onStartTraining(form: NgForm) {
    this.trainingService.startExercise(form.value.exercise);
  }

}

What is the problem?

The problem is that when I try to create my model object in this way:

return {
  id: doc.payload.doc.id,
  ...(doc.payload.doc.data() as Exercise),
};

it give me the following error on the id property on my IDE:

‘id’ is specified more than once, so this usage will be
overwritten.ts(2783)

Compiling I obtain the same error:

Error: src/app/training/new-training/new-training.component.ts:38:15 - error TS2783: 'id' is specified more than once, so this usage will be overwritten.

38               id: doc.payload.doc.id,
                 ~~~~~~~~~~~~~~~~~~~~~~

  src/app/training/new-training/new-training.component.ts:39:15
    39               ...(doc.payload.doc.data() as Exercise),
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    This spread always overwrites this property.


Error: src/app/training/new-training/new-training.component.ts:38:15 - error TS2783: 'id' is specified more than once, so this usage will be overwritten.

38               id: doc.payload.doc.id,
                 ~~~~~~~~~~~~~~~~~~~~~~

  src/app/training/new-training/new-training.component.ts:39:15
    39               ...(doc.payload.doc.data() as Exercise),
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    This spread always overwrites this property.




✖ Failed to compile.

If I remove this property and I use:

return {
  //id: doc.payload.doc.id,
  ...(doc.payload.doc.data() as Exercise),
};

I obtain no error but when the console.log() print out my result it doesn’t contains the id property.

Why? What is wrong with my code? What am I missing? How can I try to fix it?

>Solution :

This is because you have an id property in your Exercice interface.

Switching the order as follows should do the trick, according to this SO answer (I didn’t test it):

return {
  ...(doc.payload.doc.data() as Exercise),
  id: doc.payload.doc.id
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading