Difficulty dealing with Firestore using get() followed by add()

Recently started learning Vue.js and Firestore, facing a challenge with what should be a simple task.

1) I am trying to fetch default values from an existing template document in my Firestore database.

2) The goal is to use these default values to create a new record in a different collection.

I am able to successfully retrieve the default values from the template document and they are displayed correctly when using console.log. So, I expect that the variables starting with "this." now contain the correct values for creating a new document, right?

However, when I try to add a new document using these default values, the newly created document in 'nodes' collection contains blank strings instead of the values retrieved from the initial query. The fields are present but empty ("").

The function createNewLocation() is triggered by a button press on the page. While the function works, it fails to copy over the values as expected.

I have attempted various approaches without success. Could this issue be due to latency where the first query hasn't completed before the new document is created? If so, how can I overcome this obstacle?

Thank you.

<script>
import db from '../components/firebaseInit'
export default {
    name: 'loc-new',
    data () {
        return {
            //Values entered in the form
            new_loc_id: null,
            new_loc_name: null,

            //Default values placeholders used in location creation
            node_hw_ver: 0,
            node_sw_ver: 0,
            node_user_descr: '',
            node_user_name: '',
            node_type_class: '',
            node_type_id: 0,

        }
    },
    methods: {
        createNewLocation () { 
            //retrieve template /templates/(nodes)/node_templates/
            db.collection('templates').doc('nodes').collection('node_templates')
                .where('use_for_new', '==', true).get().then((querySnapshot) => {
                querySnapshot.forEach((doc) => {
                    this.node_hw_ver = doc.data().default_hw_ver
                    console.log("hw ", this.node_hw_ver)
                    this.node_sw_ver = doc.data().default_sw_ver
                    console.log("sw ", this.node_sw_ver)
                    this.node_user_descr = doc.data().default_user_descr
                    console.log("descr ", this.node_user_descr)
                    this.node_user_name = doc.data().default_user_name
                    console.log("name ", this.node_user_name)
                    this.node_type_class = doc.data().type_class
                    console.log("class ", this.node_type_class)
                    this.node_type_id = doc.data().type_id
                    console.log("id ", this.node_type_id)
                })
            })
            db.collection('nodes').add({
                    loc_id: this.new_loc_id,
                    addr: 1,
                    user_name: this.node_user_name,
                    user_descr: this.node_user_descr,
                    type_id: this.node_type_id,
                    type_class: this.node_type_class
            })
            .then(function(docRef){
                //do nothing                
            })
            .catch(function(error){
                console.error("Error adding node document: ", error)
                return null
            })

        }
    }
}
</script>

Answer №1

After some trial and error, I believe I've fixed the issue. It turns out that the promise had not returned yet, which was why the update wasn't happening. While I typically work in C and find JavaScript syntax a bit fuzzy, I managed to make it work by adding the .add() query inside the .then of the initial query. Although I know 'await' could be used for this, I found the syntax confusing in the examples I came across. There might be a cleaner approach, but this solution works for now.

In my code snippet below, I'm importing db from '../components/firebaseInit' and defining a Vue component with some data properties. The createNewLocation method queries the database to fetch a template and then uses the retrieved data to add a new node in another collection.

<script>
import db from '../components/firebaseInit'
export default {
    name: 'loc-new',
    data () {
        return {
            //Values from entry form
            new_loc_id: null,
            new_loc_name: null,

            //Holders for default values used in location creation
            node_hw_ver: 0,
            node_sw_ver: 0,
            node_user_descr: '',
            node_user_name: '',
            node_type_class: '',
            node_type_id: 0

        }
    },
    methods: {
        createNewLocation () { 

            //get template /templates/(nodes)/node_templates/
            db.collection('templates').doc('nodes').collection('node_templates')
                .where('use_for_new', '==', true).limit(1).get().then((querySnapshot) => {
                querySnapshot.forEach((doc) => {

                    this.node_hw_ver = doc.data().default_hw_ver
                    console.log("hw ", this.node_hw_ver)
                    this.node_sw_ver = doc.data().default_sw_ver
                    console.log("sw ", this.node_sw_ver)
                    this.node_user_descr = doc.data().default_user_descr
                    console.log("descr ", this.node_user_descr)
                    this.node_user_name = doc.data().default_user_name
                    console.log("name ", this.node_user_name)
                    this.node_type_class = doc.data().type_class
                    console.log("class ", this.node_type_class)
                    this.node_type_id = doc.data().type_id
                    console.log("id ", this.node_type_id)

                    db.collection('nodes').add({
                        loc_id: this.new_loc_id,
                        addr: 1,
                        user_name: this.node_user_name,
                        user_descr: this.node_user_descr,
                        type_id: this.node_type_id,
                        type_class: this.node_type_class
                    })
                    .then(function(docRef){
                        //do nothing                
                    })
                    .catch(function(error){
                        console.error("Error adding node document: ", error)
                        return null
                    })
                })

            })
        }
    }
}
</script>

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

Regex tips: Matching multiple words in regex

I am struggling with creating a simple regex. My challenge is to write a regex that ensures a string contains all 3 specific words, instead of just any one of them: /advancebrain|com_ixxocart|p\=completed/ I need the regex to match only if all thre ...

Are there any resources available to ensure my jQuery script is compatible with multiple browsers?

After realizing that Internet Explorer does not support certain selectors in jQuery, I began to question how to ensure my code will function properly during the writing process. As a Linux user, my testing options are limited to Chrome and Firefox. Is ther ...

Is it possible to use a v-for loop within F7+Vue to dynamically update the title of each accordion item?

Is there a way to dynamically update the title of each accordion-item using a v-for loop in F7+Vue? I want the title of each accordion-item to match the Title property of the objects in my myList array that is being iterated through. Here is an example: ...

Searching for an object within an array in NodeJS that is not present in another array

One of my challenges involves working with two arrays of objects: var existingUsers1 = []; existingUsers1.push({ "userName": "A", "departmentId": "1" }); existingUsers1.push({ "userName": "B", "departmentId": "1 ...

AngularJS- Efficiently loading components asynchronously within the application

As I dive into developing my app, I've decided to use AngularJS as my front-end framework. However, my lack of experience with AngularJS has presented me with some challenges in understanding its concepts and logic. Below is a rough outline of the sc ...

Merging values of different keys in a .json file

Check out my json file below: { "foo": "https://3a1821d0.ngrok.io/api/foo", "bar": "https://3a1821d0.ngrok.io/api/bar", } I am interested in changing the key 3a1821d0 to a different variable within the json structure, like so: { "some_variab ...

After the execution of the script by V8, which phase will be initiated first?

Scenario // test.js setTimeout(() => console.log('hello'), 0) setImmediate(() => console.log('world')) Simply execute node test.js using node v12.12.12 on an Intel MacBook Pro. The output may vary: hello world Sometimes it is: ...

Verify the value of the variable matches the key of the JavaScript object array and retrieve the corresponding value

array = { event: [{ key: "value", lbl: "value" }], event1: [{ key: "value", lbl: "value" }] var variable; if(variable in array){ //need to handle this case } I am looking for a function that takes the name of an ar ...

"Header background image gradually fades out and disappears as you scroll, revealing a bottom gradient effect in a React application

When I scroll, my header image fades away. I used JavaScript in my React app to achieve this effect: useEffect(() => { const handleScroll = () => { if (parallaxDiv.current) { parallaxDiv.current.style.backgroundPositionY = `${ ...

The event "click .className" within the Marionette module is failing to trigger

I'm facing an issue with some code that I've written. Here's a snippet of what it looks like: myApp.module(args, function(args){ Views.MainView = Marionette.ItemView.extend({ //template, tagName, className down: false, events: ...

"Enhance user experience with a multi-level dropdown menu feature in Bootstrap

I have been utilizing bootstrap-vue and I am trying to implement a multi-level dropdown menu for different categories. You can check out the official example on their website: <b-dropdown id="dropdown-1" text="Dropdown Button" clas ...

Adjust slider value dynamically with jQuery

I am working on a UI slider that ranges from 0 million to 20000 million. My goal is to change the displayed value when it reaches 1000 to show '1 milliard', and at 20000 to show '20 milliard'. For instance, if the value is 1100 millio ...

The websocket server implemented in Node.js with the use of the "ws" library is exhibiting a peculiar behavior where it disconnects clients at random intervals,

My WebSocket server implementation is quite simple: const WebSocket = require('ws'); const wss = new WebSocket.Server( { server: server, path: "/ws" }); wss.on('connection', function connection(ws, req) { console.log("Connect ...

Guide on displaying a document in react-doc-viewer from a protected API endpoint in either Next.Js or ReactJs

I am looking to display files in my Next.JS web application using a secure API. The API provides the following data: { "name": "Test1.docx", "contentUri": "https://api.mypurecloud.ie/api/v2/downloads/x ...

Looping the jQuery Ajax success function

Utilizing Ajax to input an array of data into a database. At the moment, when clicking on "#bookingbutton," it triggers a return block of HTML containing the ".select-room-button" button. I have incorporated the code for ".select-room-button" within the ...

Using Laravel to retrieve the selected value of a dynamically generated radio button through a for loop in jQuery

In my view, there is a form with dynamically populated radio buttons sourced from the database. The code snippet for this functionality is as follows: <div class="row"> @foreach($status as $s) <div class="col-md-6"> <label class ...

Transformation from a class component to a function component in React JS

I have a class component that I need to convert into a functional component. So, I started by refactoring the constructor. Below is the original class component: class EventCalendar extends React.Component { constructor(props) { super(props) ...

Toggling dropdown menus with conditional Jquery statements

I am experiencing some discomfort. :) I've been working on a calorie calculator that includes a dropdown for various dietary preferences. Currently, when a user clicks the button, the dropdown appears and disappears when clicking outside the button. ...

Retrieve the ReadStream from Firebase Storage and provide it as input to the Openai API

I am struggling to retrieve an image from firebase storage and transmit it to an openai endpoint Here is my current code snippet: const fileStorage = await getStorageAdmin(uid, "/sample.png"); const file = fileStorage.createReadStream(); co ...

Is it possible for a component to have multiple templates that can be switched based on a parameter?

Scenario My task is to develop a component that fetches content from a database and displays it on the page. There needs to be two components working together to create a single page, following a specific component tree structure. DataList - receives ful ...