What is the solution to the problem of a missing property in a TypeScript or Firestore project?

Here is a snippet of code from my TypeScript project:

admin.firestore().collection('posts').doc(postId).get().then((data) => {

        let likesCount = data.data()?.likesCount || 0;
        let likes = data.data()?.likes || [];
        let updateData = {};

        if (action == 'like') {
            updateData['likesCount'] = ++likesCount;
            updateData[`likes.${userId}`] = true;
        } else {
            updateData['likesCount'] = --likesCount;
            updateData[`likes.${userId}`] = false;
        }

        admin.firestore().collection('posts').doc(postId).update(updateData).then(() => {
            response.status(200).send('Done');
        }).catch((err) => {
            response.status(err.code).send(err.message);
        });
    }).catch((err) => {
        response.status(err.code).send(err.message);
    });

I encountered an error while assigning values within the if & else blocks in this code that I copied from a tutorial.

The specific error messages are as follows:

Element implicitly has an 'any' type because expression of type '"likesCount"' can't be used to index type '{}'. Property 'likesCount' does not exist on type '{}'.

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'. No index signature with a parameter of type 'string' was found on type '{}'.

I attempted to create an interface and use it like so:

interface UpdateData {
            likesCount: number,
            likes: string
        }

        let updateData = {} as UpdateData;

However, this approach resulted in another error:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'UpdateData'. No index signature with a parameter of type 'string' was found on type 'UpdateData'.

In addition, using this interface may not cover all the values associated with the data retrieved from Firestore. I want to ensure that these values still exist after updating the mentioned two fields.

If anyone could provide guidance on how to resolve this issue, I would greatly appreciate it.

Answer №1

It seems like you may be encountering an issue with TypeScript classes in general, rather than firebase specifically. Why not consider trying out my proposed solution below?

export class UpdateData {
    constructor(){
        this.likes = {};
    }
    likesCount!: number;
    likes!: {
        [key: string]: boolean;
    }
}

After fetching the data, proceed with the following code:

let updateData = new UpdateData();

updateData.likesCount = action == 'like' ? ++likesCount : --likesCount;
updateData.likes[`${userId}`] = action == 'like';

console.log(updateData);

P.S. I opted for conditional statements over an if-else block for simplicity's sake, but your existing blocks should function just as effectively.

You can also access a working example online here: https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAYwDYEMDOa4FUwBMUzAAiBKcA3gLABQcdiEAdmjFAK4IzQAUAlFbXpCYACwCWaAHRIxAa2CYAvBQC+AbhpCVm+jPloAwhDaMYAQgBccRmwC2AI2BQNgunoWWKOoXQDa8gE8rFigxRgBzAF0rewgIJGAURhctGm1qGgB6TNw7WwC4fBgUGgT4FE4xJjhlAHJ3WpcyuHdDY1MauABGJuB4NjQnAElcTtqUewQugCYAZkaaUr64NjwCYlJOxmAAd2w1whJivhcaVaKN4uk5BSMTeGUKmCrGGrqGuAB+OABqH9a7h0rABaYEA9owFzndZHFDXfS+AAGABJyANhrgVIjIp0ni83nB6jcFhlqAgmGh4sBpBBwtxoYdSLw1EA

I hope this information proves helpful!

Answer №2

Take a look at the following suggestion:

interface UpdateData {
            likesCount: number;
            likes: string;
            [key:any]: any;
        }

This code snippet declares that a property of type string can be used as an indexable signature.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Overlapping Issue with Angular Bootstrap Dynamic Dropdown Menu

I'm currently working on creating a dynamic menu using Angular and Bootstrap for Angular. My main issue right now is that the submenus are overlapping each other when displayed on the page. To tackle this problem, I started off by referring to the ex ...

What could be causing the rapid breakage of the socket in Ionic 3's Bluetooth Serial after just a short period

Although the code appears to be functioning correctly, it loses connection shortly after establishing it. This snippet contains the relevant code: import { Component } from '@angular/core'; import { Platform, NavController, ToastController, Ref ...

Can anyone provide guidance on extracting HTML elements from a stream of objects within rxjs?

In my Angular 8 project, I am working with a WordPress RSS feed to create a news scroller. The information from the feed is parsed into a JavaScript object using rss-parser from node.js. One of the challenges I am facing is extracting a HTTP link, an imag ...

Encountered an Angular 2 error: NullInjectorError - Http provider not found

I've encountered an issue while trying to access a JSON GitHub service, receiving the error message NullInjectorError: No provider for Http! Although I've attempted to add providers throughout the code, my efforts have been unsuccessful. I' ...

Why are all my requests being denied for the chat-app with nested collections in Firestore Rules?

I am encountering a challenge with configuring Firebase Rules for my chat app. I want to restrict users from accessing conversations they are not part of, but when I try to implement the rules, access gets denied even when checking for conversation existen ...

Having trouble establishing a connection with Db2 while using protractor

Encountering an issue when attempting to establish a connection with a remote DB2 database, resulting in the following exception: SQL30081N A communication error has been detected. The communication protocol in use is 'TCP/IP'. The com ...

Transform a nested AngularJS service into an Angular Observable service

Currently, I am working on migrating AngularJS(pre 1.5) services that use nested calls to a project being rebuilt in Angular(11). The challenge I'm facing is how to rewrite these services using RXJS. I have been searching for resources or detailed ex ...

There is a complete absence of text appearing on the html page when Angular is

Currently, I am in the process of learning Angular during my internship. As part of the requirements, I have been tasked with developing a client-server application using Angular as the frontend framework and Spring as the backend solution. Within the proj ...

The outdated angular-cli version is causing issues with running ng serve

I am experiencing issues with updating my angular-cli using the command npm install -g @angular/cli. I encounter console errors such as warnings and permission denials. Despite deleting the npm cache, the problem persists. When attempting to run ng serve ...

Enforcing type safety with Angular's global trackBy property directive

I am looking to create a custom trackBy directive that allows me to specify a property name for tracking ngFor items. Here is the code snippet: import { NgForOf } from '@angular/common'; import { Directive, Host, Input } from '@angular/core& ...

Have I repeated myself in defining my class properties?

Currently, I'm enhancing my understanding of Typescript with the development of a discord.js bot. However, I have come across a piece of code and I am uncertain about its redundancy: import Discord from 'discord.js'; export default class B ...

The stack property of [object Object] cannot be updated, as it only has a getter method

I can't figure out why I'm receiving this specific error in the Plunker below. Cannot set property stack of [object Object] which has only a getter Access the Plunker here: https://plnkr.co/edit/IP1ssat2Gpu1Cra495u2?p=preview The code causi ...

Including a screenshot in the allure report

I am struggling to figure out how to include a screenshot in my allure report using cypress and mocha-allure-reporter. Despite the report generating correctly, I have not been able to find any examples or guidance on how to set it up and add screenshots ...

What is the best way to show a spinner while Vue.js is retrieving data from Cloud Firestore?

Currently, I'm utilizing Firebase and Vue.js with Vuex. Within the onAuthStateChanged() method, I am fetching data from the posts collection. This process takes some time to display, so in the meantime, I wish to show a spinner to indicate to the user ...

Error encountered while downloading file from S3 on NextJs due to network issue

I have encountered a network error while trying to download a file from Amazon S3. Despite configuring my Amazon config file correctly and using the S3.getObjectURl() method for the download, it still fails. Below is the snippet of my code: const AWSDownlo ...

Patience is key when hoping for a reaction nested within another in Redux

I am attempting to recycle one of my actions. Here is the structure of my actions: const actions = { changeStage: (data: Object) => (dispatch) => { return new Promise((resolve) => { dispatch({type: ACTION_TYPES.Loader, payload: ...

Which is the best place to initialize variables in Angular: Constructor, Declaration, or ngOnInit, including observables?

Here is an Angular component code snippet: export class ListComponent implements OnInit { showComments: boolean = false; posts$: Observable<PostModel[]>; constructor(private postService: PostService) { } ngOnInit() { this.posts$ = t ...

What causes the variation in typing behavior between specifying props directly on a component versus nesting them inside another prop?

Understanding the next component might be a bit tricky, so let's delve into it (Check playground): type Props<T> = { initValue: T, process: (value: T) => T } export const Input = <T,>({ initValue, process, }: Props<T>): ...

Leveraging parameters within a sequence of object properties

Within the realm of Angular, I am dealing with interfaces that take on a structure similar to this (please note that this code is not my own): export interface Vehicles { id: number; cars: Car; trucks: Truck; } Export interface Car { make: ...

What is the best way to bring in Javascript files to a specific component along with HTML and CSS?

` <script src="./jquery.min.js"></script> <script src="./bootstrap.bundle.min.js"></script> <!-- Core plugin JavaScript--> <script src="./jquery.easing.min.js"></script> <!-- Page level plugin JavaScr ...