struggling with managing an array of Vue3 refs

Having an issue with handling vue3 refs, specifically when retrieving data from Firestore. When logging the [documents], everything seems to work fine. However, I run into errors when trying to access values from an array within a document.

For example,

The desired value is:

abc1 (displayName of the first array)

I attempted:

console log

0. documents (works, results below)

1. documents.value.displayName (error)

2. documents.value[0].displayName (error)
Uncaught (in promise) TypeError: Cannot read property '0' of null
    at setup (Write.vue?125b:56)

but encountered failure.

How can I successfully retrieve values from refs arrays?

Log document

RefImpl {_shallow: false, __v_isRef: true, _rawValue: null, _value: null}
__v_isRef: true
_rawValue: Array(2)
0: {displayName: "abc1", orgName: "amazon", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="53323232133232327d303034363e30">[email protected]</a>", regDate2: "2021-7-27", …}
1: {displayName: "abc2", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5c3e3e3e1c3e3e3e73393d3f37">[email protected]</a>", orgName: "google", …}

setup Function

    setup() {
      const title = ref('')
      const contents = ref('')
      const { user } = getUser()
      const userUid = user.value.uid
      const { documents } = getCollection('user')
      console.log(documents, 'documents log')
      console.log(documents.value[0].displayName, 'documents value log')
      return {title, contents, user, documents }
    }

getCollection.js

const getCollection = (collection, query) => {

  const documents = ref(null)
  const error = ref(null)

  // register the firestore collection reference
  let collectionRef = projectFirestore.collection(collection)

  if (query) {
    collectionRef = collectionRef.where(...query)
  }

  const unsub = collectionRef.onSnapshot(snap => {
    let results = []
    snap.docs.forEach(doc => {
      results.push({...doc.data()})
    });
    
    // update values
    documents.value = results
    error.value = null
  }, err => {
    console.log(err.message)
    documents.value = null
    error.value = 'could not fetch the data'
  })

  watchEffect((onInvalidate) => {
    onInvalidate(() => unsub());
  });

  return { error, documents }
}

export default getCollection

Answer №1

fetchData retrieves information asynchronously after sending it to the server. Keep in mind that console.log displays a live link to the object, so the most recent data will appear in the browser console rather than the data at the time of logging. If you want to see the data as it was when logged, use JSON.stringify:

export default {
  setup() {
    //...                👇
    console.log(JSON.stringify(information.value), 'information log')
  }
}

The current log may display null, since the reference has not been updated.

Solution

To log the title of the first element in information, utilize a watch on the information reference, triggering whenever information.value changes:

import { watch } from 'vue'
 
export default {
  setup() {
    const { information } = fetchData('user')

    watch(information,
          newValue => {
            console.log(newValue?.[0].title)
          },

          // include `deep` flag to monitor property alterations in array elements
          { deep: true }
    )
  }
}

demo

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

"Is there a specific way to designate the content type as multipart form data when using Axios

I am experiencing difficulty with axios as I am unable to set the content type to multipart/form-data. Below is the code snippet: function (config) { // Do something before request is sent const isLogin = authService.isLogin(); if (isLogin) ...

What is the method for concatenating two strings in JavaScript without any whitespace in between?

When working with two strings involving time, consider the following scenario: var gettime= $("#select-choice-2 :selected").text(); The above code returns a time value in 24-hour format, such as 17:45 However, if you require the time to display in the ...

Could someone provide me with guidance on how to troubleshoot this error message?

[0] Unhandled rejection MongoError: (Unauthorized) not authorized on admin to execute command { listIndexes: "sessions", cursor: { } } [0] at MongoError.create (/Users/biggahd/Desktop/Mars-EMS-1/backend/node_modules/mongodb-core/lib/error.j ...

Encountering issues with parsing JSON data following its transmission through an Ajax request

Client Side Once an object has been processed with JSON.stringy, it is sent in this format to a node-server via a POST request: {"id":"topFolder","parentPath":null,"name":"newProject","is":"root","children":[]} The request is sent from the client side u ...

Steps to have index.html display when running the build command in a Svelte project:

Greetings everyone, I'm brand new to using Svelte and have a question that's been on my mind. I recently developed a small app in Svelte that works perfectly fine during development. However, when I run npm run build for production, the output ...

How come I keep running into the "is not a function" issue when trying to use the generateRequest function with Polymer's iron-ajax

Oops, it seems like there was an error: Uncaught TypeError: this.$.ajax.generateRequest is not a function. The issue seems to be in assets-ajax.html at line 23. <dom-module id="assets-pull"> <style> </style> <template> <but ...

VS Code using Vue is displaying an error message stating: The property '' does not exist on type '{}'.ts(2339)

While working in Visual Studio Code, I came across the following code snippet: <script lang="ts" setup> const parseCSV = () => { // Code omitted for brevity } } </script> <template> <button @click="parseCSV ...

Guide to refreshing the modal component with updated properties

In my application, I have created a modal component for managing recipes. This modal allows users to save recipes to a list. let modal = <Modal saveRecipe={this.saveRecipe} closeModal={this.toggleModal}/> However, I also want to utilize the same m ...

Transform large GeoJSON files into TopoJSON format

I am struggling to convert a large GeoJSON file that is approximately 1.4GB in size. The command line tool is unable to handle the file due to its filesize. I typically use the topojson command tool like so: topojson {{ input file }} >> {{ output fi ...

The Slack Bot is having trouble downloading files from direct messages, but it is successfully downloading them when uploaded to a channel

I have developed a program to retrieve files using a code snippet provided by a Slack bot. Below is the code: var https = require('https'); var fs = require('fs'); var downloadFile = function (url, dest){ var slug = url.split(&apos ...

Issue encountered while adding a value from MongoDB to a list

Encountering an issue when attempting to add an element to an array using a for loop MY CODE router.get('/cart', verifyLogin, async (req, res) => { var products = await userHelpers.getCartProducts(req.session.user._id) console.lo ...

What is the best way to set the page title on a server-rendered component when using the Next.js app router?

When loading a blog post from the server, I have access to details like the title of the post. However, based on the app router migration guide, this information is located outside my page. How can I update it? For more information, refer to the documenta ...

Unveiling the secrets of using VueJS modifiers in PUG

Can you provide guidance on using modifiers with Pug? I attempted the following: my-component(:options.sync="addresses") my-component(':options.sync'="addresses") Both resulted in a syntax error, unexpected token. my-component(:options="addr ...

The Javascript Date constructor struggles to interpret date strings in certain timezones that are not enclosed in brackets

Take a look at the examples below: new Date("Wed, 28 May 2014 09:50:06 EEST"); // Invalid Date new Date("Thu, 26 Jun 2014 09:09:27 EDT"); // OK, is parsed new Date("Wed, 28 May 2014 09:50:06 (EEST)"); // OK, is parsed new Date("Thu, 26 Jun 2014 09:09:27 ( ...

What is the process for converting several files into a base64 string?

I have a component set up like this: <input type="file" multiple @change="toBase64Handler($event)"> <script> data() { return { files: [], } }, methods: { tobase64Handler(event) { // implementation } } </script> I w ...

When working with Angular 2 and Typescript, a common error message that may be encountered is "TypeError

Currently diving into Angular 2 and encountered a stumbling block while attempting to create a service. Despite my efforts in finding a solution, I seem to be missing something crucial. Error: A problem arises in angular2-polyfills.js:1243 with the error ...

Having trouble retrieving information from Node.js service in AngularJS 2

I am currently expanding my knowledge of Angular and attempting to retrieve data from a node js service using Angular 2 services. When I access the node js services directly from the browser, I can see the results. However, when I attempt to fetch the dat ...

Importing vs Referencing Videos in Next.js - What is the Best Practice for Video Integration in Next.js?

I'm looking to use a video as a background in my banner design. Typically, with images in Next.js, I would import them and then pass the import as src (for example: import img from '@images/about-us-page/img.svg'). However, when attempting ...

Enhancing Values Across a Timeframe Using JavaScript

Last time, I asked about my code. Here is what I have currently: var secs = 100; setInterval(function() { var $badge = $('#nhb_01'); $badge.text((parseFloat($badge.text())+0.01).toFixed(2)); }, secs); I want the counter to increase by ...

Sending a message in the DELETE route using express.js

I'm having trouble displaying a message after deleting a user. I attempted to use req.session properties and then retrieve them in the GET route, but they seem to not be available. Can anyone suggest a solution for fixing this code? router.get("/", ...