What is the best way to set a Firestore data field as a variable?

I am working with a firebase collection named 'messages', where I add documents as follows:

this.afs.collection('messages').add({ 'qn': message, 'student': this.student, 'upvotes': this.upvote });

The upvotes field is controlled by an upvote or downvote button. Whenever one of them is clicked, I trigger this method:

increment(messageId) { //decrement(messageId) for the downvote button
this.upvote += 1; //-=1 for the downvote button   
this.messageDoc = this.afs.doc('messages/' + messageId);
this.message = this.messageDoc.valueChanges();
this.afs.doc('messages/' + messageId).update({
  upvotes: this.upvote
});
}

The issue here is that I initialized the upvotes variable like this: private upvote: number = 0;

As a result, if I refresh the page and click the upvote or downvote buttons, the value will simply start from 0 again, because the upvote variable does not store the actual database value. To address this, I want to assign the data from the upvotes field in the document to the upvote variable - how can I achieve this?

Edit: I managed to resolve this problem using the following solution:

increment(messageId) {
this.upvote += 1;
let self = this;
let messageDoc = firebase.firestore().collection('messages').doc(messageId);

return firebase.firestore().runTransaction(function (transaction) {
  return transaction.get(messageDoc).then(function (sfDoc) {
    let upVote = sfDoc.data().upvotes + self.upvote;
    transaction.update(messageDoc, { upvotes: upVote });
    self.upvote = 0;
  });
}).then(function() {
  console.log("Transaction successfully committed!");
}).catch(function(err) {
  console.log("Transaction failed: " + err);
});
}

Answer №1

If you need to handle updates with Transactions

let self = this;
let messageDoc = firebase.firestore().collection('messages').doc(messageId);

return firebase.firestore().runTransaction((transaction) => {
    // This block might run multiple times in case of conflicts.
    return transaction.get(messageDoc).then((sfDoc) => {
        let upVote = sfDoc.data().upvotes + self.upvote;
        transaction.update(messageDoc, { upvotes: upVote });
    });
  }).then(() => {
      console.log("Transaction successfully done!");
  }).catch((err) => {
      console.log("Transaction error: ", err);
  });

Remember to include

import * as firebase from 'firebase';

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

What is the best way to implement a switch case with multiple payload types as parameters?

I am faced with the following scenario: public async handle( handler: WorkflowHandlerOption, payload: <how_to_type_it?>, ): Promise<StepResponseInterface> { switch (handler) { case WorkflowHandlerOption.JOB_APPLICATION_ACT ...

Is the relevance of Angular 1.x still prevalent in today's development landscape

Considering I have several projects in angular 1.x, I'm contemplating whether it's truly essential and efficient to upgrade them to angular 4 or a later version. The smaller dashboards do not necessarily require an update since they are only use ...

Can TypeScript be used to generate a union type that includes all the literal values from an input string array?

Is it feasible to create a function in TypeScript that takes an array of strings and returns a string union? Consider the following example function: function myfn(strs: string[]) { return strs[0]; } If I use this function like: myfn(['a', &a ...

A guide to efficiently removing an element in Angular using TypeScript by considering certain properties

I need help removing an element from an array based on any property such as its key, name, or email. HTML <tr *ngFor="let person of persons;" (click)="remove(person.key)"> <td>{{person.key}}</td> <td>{{person.name}}</td> ...

Grunt is your go-to resource for instructions on executing these tasks before the main program

Before launching my app, I need to make sure a specific grunt task is executed first: node app.js I'm having trouble finding information on how to automatically run and complete a Grunt task before initiating a node command. In particular, I have T ...

What is the best approach to managing a 204 status in Typescript in conjunction with the Fetch API

Struggling to handle a 204 status response in my post request using fetch and typescript. I've attempted to return a promise with a null value, but it's not working as expected. postRequest = async <T>(url: string, body: any): Promise ...

Navigating Mixins in Ember CLI Typescript

I'm curious about the best approach for handling mixins in a typed Ember application. While removing mixins from the application is ideal, many addons do not yet support TypeScript. So, how can we effectively utilize Ember Simple Auth's applicati ...

An error has occurred: Unable to access the 'group_status' property of an undefined console object

I have been encountering a persistent error in the console, with it continuously increasing. The issue arises when I utilize two-way binding with ngModel alongside an interface. To provide further insight, I have included screenshots of my code below. Scr ...

Getting the Full Error Message in Axios with React Native Expo

I'm encountering a network error while using Axios with React Native. Previously, when working with React JS on the web, I could console log the error or response and see all the details. However, in Expo, all I get is "Axios error: Network error" wh ...

How can the value be accessed when using getElementById in Angular for <mat-select> elements that do not have a value attribute?

Within a loop, I have an element that has a dynamically generated id: <mat-select multiple class="dw-input" [value]="element.txn_type_id ? element.txn_type_id.split(',') : []" id="field-{{element.Name}}-txn_type_id&quo ...

Using the currency pipe with a dynamic variable in Angular 2

My application utilizes CurrencyPipe, The current implementation is functional, <div class="price">{{123 | currConvert | currency:'USD':true:'3.2-2'}}</div> Now, I need to dynamically pass the currency from a model varia ...

Ways to implement a filter pipe on a property within an array of objects with an unspecified value

Currently, I'm tackling a project in Angular 8 and my data consists of an array of objects with various values: let studentArray = [ { Name: 'Anu', Mark: 50, IsPassed: true }, { Name: 'Raj', Mark: 20, IsPassed: false }, { Na ...

Generating HTML content using Angular 8 and JSON data

Currently, I am managing an Angular Storybook that consists of various components. Within the stories.ts file of a component, there is a JSON snippet containing properties such as the content of a DIV element, shown below... { "accordionLink": ' ...

Error in WebStorm: Troubleshooting HTML file issue in Angular application

I encountered an error in WebStorm while working on a new project where I was testing a form. The issue only arises when I run ng serve, although no errors are reported and the application runs smoothly. To troubleshoot, I tried deleting my node_modules f ...

Guide to accessing the content of pure ES6 modules directly in the Chrome console without the need for Webpack

Situation: When using tsc to compile code for es6, the scripts function properly once they are served from a server. However, I am unsure of how to access variables within modules through the console. The file names do not seem to be available as objects ...

The function cb() was never invoked, resulting in an error during the npm install process

I'm having trouble installing node modules in my angular project. Running npm install gives me this error: npm ERR! cb() never called! npm ERR! This is an error with npm itself. Please report this error at: npm ERR! <https://npm.community> ...

Configuring routes for Angular4 router is a vital step in creating a

Issue: I am currently setting up routes for my application, aiming to structure the URL as https://localhost:4200/hero=id, where the 'id' will be dynamically selected. However, this setup is not functioning as expected. If I attempt to use a URL ...

Creating a file logging system with log4js to capture Console logs

Is there a way to automatically log all console logs, including failed expectations and exceptions, to a file without using try and catch in JavaScript? In Java's LOG4j, the rootlogger feature does this by default. Is there a similar functionality ava ...

Troubleshooting: Issues with Angular2 compatibility on Safari version 9.1.2

I am encountering an issue with running my angular2 app on Safari 9.1.2. It works fine on all higher versions of Safari as well as other browsers such as Chrome, Firefox, Opera, and Edge. However, when I try to run it on Safari 9.1.2, I receive the followi ...

retrieve a shared string from an array when toggled

Regarding the use of SelectionModel for mat-checkbox, a function is called on each click: toggleSelection(row) { this.selection.toggle(row); console.log("Selection"); console.log("this", this.selection.selected); this.selection.selected.f ...