1

I'm trying to trigger GA events using Nuxt. It's successfully working but it's only returning the first one it runs into because of document.querySelector rather than querySelectorAll. I have tried the spread operator and a for() but still no luck - the compiler just says cannot read property txt of undefined.

Here's my v-for:

<ul>
 <li class="li-item" v-for="item in items" :key="item.id" @click="doGA" :data-txt="item.name">
  {{ item.name }}
 </li>
</ul>
<ListDetails
   :items="[
     {
       name: 'Lorem',
     },
     {
       name: 'Ipsum',
     },
     {
       name: 'Dolor',
     },
   ]"
/>
methods: {
  doGA(){
    this.$ga.event({
       eventCategory: "Ext links",
       eventAction: "click",
       //this.dataset.txt does not work below here either
       eventLabel: document.querySelectorAll('.li-item').dataset.txt;
    });
  }
}

So when a user clicks 'Ipsum' it's returning 'Lorem' in GA and likewise for 'Dolor' it will do the same. It is because I have used document.querySelector rather than selectorAll as I have said above, but I can't get all() to work properly.

As we know querySelector will return this first one the browser finds.

0

1 Answer 1

2

TLDR: querySelector and querySelectorAll are usually not the way to go in VueJS, if you want to select something. Either bind with state or find it with a this.$refs[...].


With a template looking like this

<ul ref="list">
  <li v-for="item in items" :key="item.id" @click="doGA(item.name)">
    {{ item.name }}
  </li>
</ul>

You could call the method on each of your element like this

methods: {
  doGA(itemName){
    this.$ga.event({
       eventCategory: "Ext links",
       eventAction: "click",
       eventLabel: itemName
    })
  }
}

Otherwise, if you want to send all of them, you can do the following

<template>
  <ul>
    <li v-for="item in items" :key="item.id" @click="doGA">
      <span :ref="`item-${item.id}`" :data-txt="`fancyText-${item.id}`">
        number >> {{ item.id }}
      </span>
    </li>
  <ul>
</template>

<script>
export default {
  data() {
    return {
      items: [
        {
          id: 1,
          name: 'Lorem',
        },
        {
          id: 2,
          name: 'Ipsum',
        },
        {
          id: 3,
          name: 'Dolor',
        },
      ],
    }
  },
  methods: {
    async doGA() {
      for (const item of this.items) {
        console.log('element found', this.$refs[`item-${item.id}`][0].dataset.txt)

        await this.$ga.event({
          eventCategory: 'Ext links',
          eventAction: 'click',
          eventLabel: this.$refs[`item-${item.id}`][0].dataset.txt,
        })
      }
    },
  },
}
</script>

Notes

  • $refs is the way to go in VueJS, rather than querySelector.
  • async/await may be useful if you do care about the order, if you don't and only want to send them, I guess that you can pass on this one.
  • You can remove the spans, I let it for visibility mainly.
  • I used data here, but this should behave pretty much the same with any props.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.