# [Vue.js] Vue JS Vuetify menu named slot activator is not binding to the template, but going to default

I cannot seem to get the example code for a Vuetify v-menu to work inside my PWA app, but it works normally in a Fiddle (e.g. https://jsfiddle.net/tjw13yz4/27/)

The problem is: the activator slot content doesn’t appear.

By debugging the vuetify source code, there is found that the activator template turns up under the “default” slot (where all the hidden content is), not in the named activator slot (where the visible button/click area should be).

there is simplified my app to the bare bones (originally I had dynamic components, forms, APIs etc) so I’ve reduced it down to just a v-menu inside the top-level v-app element, and removed all the routers, stores and other plugins. It’s as simple as I can get it, but still doesn’t work. the only difference left between the fiddle and my local app is the build system.

there is also tried changing/removing the slot props and the on binding through to the button, which does modify how the named slot is internally represented in Vuetify (or Vue). However neither verison with or without props binds the named-slot properly.

I also npm updated and rebuilt (suggested in another SO), so I’m on the latest vue.js 2.6.10 and Vuetify 1.5.14.

there is also ensured when wrapping in <v-app></v-app> (but that happened when I installed the Vuetify plugin) as noted in other SO’s.

I also read this SO which I found useful in debugging.

I’ve tried putting slot=activator directly on HTML tag, rather than using the template.

And I probably tried a dozen other things, (initially I just had a problem with the on for v-on not being defined, but it was due to this underlying problem).

These are my simplified files - it’s all pretty standard:

App.vue.js (with/out props for on-event binding)

<template>
<v-app>

<v-menu offset-y>
<template v-slot:activator>
<v-btn color=”primary” dark>Dropdown</v-btn>
</template>

<p>The menu content</p>
</v-menu>

<v-menu offset-y>
<template v-slot:activator=”{ on }”>
<v-btn color=”primary” v-on=”on” dark>Dropdown2</v-btn>
</template>

<p>The menu2 content</p>
</v-menu>

</v-app>
</template>

main.js

import vue.js from “vue”;
import “./plugins/vuetify”;
import App from “./App.vue”;
new Vue({
render: h => h(App)
}).$mount(“#app”); plugins/vuetify.js import vue.js from ‘vue’ import Vuetify from ‘vuetify/lib’ import ‘vuetify/src/stylus/app.styl’ Vue.use(Vuetify, { iconfont: ‘md’, }) index.html When it runs, I set a breakpoint in node_modules/vuetify/src/components/VMenu/mixins/menu-generators.js and it returns null here because neither type of slots are set: genActivator: function genActivator() { if (!this.$slots.activator && !this.$scopedSlots.activator) return null; In my app, the Chrome debug inspector shows the v-btn is next to the p tag under the default$slot, but it should be under its own one.

In the working Fiddle by contrast, when debugging the same function, I see the activator node under $scopeSlots when I include the v-on=on event binding, and under the$slots if not. And it works fine.

Why might the v-slot=activator statement not take effect?

### Solution :

After reading this answer: https://stackoverflow.com/a/55268990/209288 I found that the older (pre vue.js v2.6) syntax worked OK, both in my stripped-down app, and then also in place in my original component.

<template slot=”activator” slot-scope=”{ on }”>

Therefore I realised my app must have still been running an older version, even though I’d used the “Build” option in the Vui UI after doing the npm update.

I just stopped and re-started the vue-cli-service serve command (in the UI) and now it all works as expected!

So I guess I was still running vue.js v2.5.22 and the build from VSCode was just hot-reloading some parts.

So the lesson is: after doing an npm update, shut down and restart everything, the build server, VSCode debugger, chrome instance.

# [Vue.js] How to access data in custom component?

there is a simple vue.js application that is structured as follows:
there is an App.vue.js component and a Card.vue.js component

In my App.vue.js there is created the following data:

{
id: 1,
name: “Frenkie de Jong”,
position: “midfielder”,
country: “The Netherlands”,
image: “frenkie_de_jong.jpg”,
value: 20000000,
club_id: 2
},
{
id: 2,
name: “Mathijs de Ligt”,
position: “defender”,
country: “The Netherlands”,
image: “mathijs_de_ligt.jpg”,
value: 20000000,
club_id: 2
}….
],
clubs: [
{ id: 1, name: “Liverpool”, logo: “Liverpool.png” },
{ id: 2, name: “Ajax Amsterdam”, logo: “ajax_amsterdam.png” }

]

For each player, I’m creating a card, which shows all relevant information (value, country, etc.). This is already working using a v-for from the App.vue.

However, now I would also like to show the club of each player. The clubs are linked to the player with the club_id’s. What would be the best practice to do this?

I was thinking of one of the two following options:

Find a match for the club in App.vue: iterate over all players and if the player.club_id == club.id, we send through the player and the club to the Card component and create a new card.
Find a match for the club in Card.vue: iterate over all players and for each player, send through the player and the list of all clubs to the Card component. In Card.vue.js I then need to create a function which finds the match between the two.

What would be the best way of doing this (in terms of performance)? Or are there maybe better options?

Thanks in advance!

Jeroen

### Solution :

Map the club data as object so you don’t have to perform find operation for each player, It will give you club in O(1) time rather than O(n) e.g make a computed prop mappedClubs and pass it in player cards

mappedClubs(){
return this.clubs.reduce((r,c) =>{
r[c.id] = r
return r
},{})
}

and in the card component just access club information something like that

<div> club name : { mappedClubs[player.club_id].name} </div>

### Solution 2:

One thing you can do in order to avoid a second iteration is to use a Map for the clubs.

data () {
return {
players: [/* … */],
clubs: new Map([
[1, { name: “Liverpool”, logo: “Liverpool.png” }],
[2, { name: “Ajax Amsterdam”, logo: “ajax_amsterdam.png” }]
])
}
}

So that you can use this method in order to get the club information depending on the provided clubId.

methods: {
getClubById (clubId) {
return this.clubs.get(clubId)
}
}

Putting it all together:

<Card
v-for=”player in players”
:key=”player.id”
:playerClub=”getClubById(player.club_id)”
/>

I personally like this approach more as you have to iterate over the players array only once, and getting a specific club requires O(1) time complexity.(Here is more about this)

# [Vue.js] Calling A function using vue.js components and properties

My program is creating templates and adding a button, the button should call a function when clicked with the parameter of the id, however, it won’t call the function with the correct parameter

there is tried adding {id} and :onClick=”addThisToCart({id} but getting a ton of errors.

Heres my code

Vue.component(‘movietable’, {
props: [‘title’, ‘price’, ‘mid’],
template: 
<tr>
<td>{title}</td>
<td>{price}</td>
<td>
<div class=”quantity”>
<button onClick=”addThisToCart({mid}”>You clicked me { count } times.</button>
</div>
</td>
</tr>
,
data: function () {
return {
count: 0
}
},
});

mid is being defined in the properties section of the vue.js element
and then the function

var cart = 0;
function addThisToCart(movieId) {
var movieId = this.mid;
this.cart += 1;
this.cart += 1;
console.log(movieId);
console.log(cart);
}

It should add +1 to cart every time the button is clicked, however, getting a ton of errors and instead of sending ‘4434’ it is sending {mid}

### Solution :

You can use

<button @click=”addThisToCart(mid)”>You clicked me { count } times.</button>

No curly braces for the argument of the function.

# [Vue.js] Automatically fetch data from API within hybrid app

Im setting up an hybrid app using Cordova. I need to match a GET request to a server to fetch some data thats in JSON format, this data from the server automatically updates with new data every now and then, several times a day at a non-consistent time.

My goal is to ping a notification on the phone, via a Cordova plugin whenever the data on the server changes, I need to somehow automatically listen and dynamically fetch the new data whenever it changes, how would one recommend I do this and potentially with what Cordova plugin? I need to use as little mobile data as possible, but on wi-fi it shouldnt be a problem.

### Solution :

From the description of what you are trying to accomplish, you should consider push to device instead of doing GETs

# [Vue.js] Vue template object key alternative reference without implicitly calling with key name

there is an object which is retrieved from an API and key names are unknown. Let’s assume it will come in the following format:

var attributes = {
“Colour”: [“red”, “black”, “purple”],
“Size”: [“8.0”, “8.5”, “9.0”, “9.5”, “10.0”]}

How can I access this data directly in vue.js without knowing keys? I know the following would work if I had known the keys, but when looking for an option where I can refer to the arrays without knowing the key names, like normal Javascript values are accessed through key name (square brackets).

<table>
<tr>
<th v-for=”(values, name) in attributes”> [[ name ]]</th>
</tr>
<td>
<select”>
<option v-for=”value in attributes.Colour”> [[ value ]] </option>
</select>
</td>
<td>
<select”>
<option v-for=”value in attributes.Size”> [[ value ]] </option>
</select>
</td>
</table>

there is tried this so far (e.g. attributes[name]), which does not seem to be correct vue.js template syntax:

<table>
<tr>
<th v-for=”(values, name) in attributes”> [[ name ]]</th>
</tr>
<td v-for=”value in attributes[name]“>
<select”>
<option> [[ value ]] </option>
</select>
</td>
</table>

### Solution :

You need to do something like this.
Since the attributes is an object with dynamic keys, loop through the object to get the keys.
Then loop through each of the keys of the object attributes to get array list.
Also, the <td> tag should be wrapped inside a <tr> tag

function callMe(){
var vm = new Vue({
el : ‘#root’,
data : {
attributes : {
“Colour”: [“red”, “black”, “purple”],
“Size”: [“8.0”, “8.5”, “9.0”, “9.5”, “10.0”]}
},
methods: {

}
})
}
callMe();
<script src=”https://cdn.jsdelivr.net/npm/vue@2.5.11/dist/vue.js"></script>
<div id=’root’>

<table>
<tr>
<th v-for=”(item, key, index) in attributes “> { key } </th>
</tr>
<tr>
<td v-for=”(item, key, index) in attributes”>
<select>
<option v-for=”name in item”> { name } </option>
</select>
</td>
</tr>

</table>

</div>
</div>

### Solution 2:

You can use indexes. See: https://vuejs.org/v2/guide/list.html#Mapping-an-Array-to-Elements-with-v-for.

<table>
<td>
<select v-for=”(value, index) in attributes”>
<option> { attributes[index] } </option>
</select>
</td>
</table>

I’m also somehow lost in the code, because I’m not sure if you want to render more options, selectsor tds. In my example there will be rendered a number of options based on the attributes that you pass into select’s v-for.

# [Vue.js] How can I use conditional Template tags inside a Vue SFC

there is two modes of using my application, an embedded and non-embedded mode. For the embedded (think iframe) mode I don’t want to show the site header and footer. I tried using v-if and v-else in App.vue.js but Visual Studio Code complains about having multiple template root elements. This seems like it should be allowed:

<template v-if=”embedded”>
<div id=”app”>
<MyContent/>
</div>
</template>
<template v-else>
<div id=”app”>
<TheHeader/>
<MyContent/>
<TheFooter/>
</div>
</template>

I’d appreciate any thoughts on this. Is it a bug in VS Code? Is this just not allowed?

Thanks.

### Solution :

In vue2 with regular .vue.js files you must have a single root. So you could accomplish this by wrapping the entire thing in a div.

<div>
<template v-if=”embedded”>
<div id=”app”>
<MyContent/>
</div>
</template>
<template v-else>
<div id=”app”>
<TheHeader/>
<MyContent/>
<TheFooter/>
</div>
</template>
<div>

You can also accomplish what you are saying using a functional component, but i would avoid that unless you are familiar with a more jsx style or have stronger js knowledge with hyperscript. https://zendev.com/2018/05/07/multi-root-vue-components.html

NOTE: Vue3 has multiroot templates planned, so this should be possible in the future

### Solution 2:

you can try below to load the components inside <div id=”app”> conditionally

<template>
<div id=”app”>
<div v-if=”embedded”>
<MyContent/>
</div>
<div v-else>
<TheHeader/>
<MyContent/>
<TheFooter/>
</div>
</div>
</template>

# [Vue.js] What pattern prefer to use when combine Laravel and Vuejs

As I know, there are 2 ways to use Vuejs in view: inline-template and component.

#1. Inline-template

I gonna use the code from series Let’s Build A Forum with Laravel and TDD for express my point.

ThreadsController:

public function show($channel, Thread$thread, Trending $trending) { if (auth()->check()) { auth()->user()->read($thread);
}

$trending->push($thread);

$thread->increment(‘visits’); return view(‘threads.show’, compact(‘thread’)); } View (threads.show) @extends(‘layouts.app’) @section(‘head’) <link rel=”stylesheet” href=”/css/vendor/jquery.atwho.css”> @endsection @section(‘content’) <thread-view :thread=”{$thread }” inline-template>
<div class=”container”>
<div class=”row”>
<div class=”col-md-8” v-cloak>
@include (‘threads._question’)

<replies @added=”repliesCount++” @removed=”repliesCount–”></replies>
</div>

<div class=”col-md-4”>
<div class=”panel panel-default”>
<div class=”panel-body”>
<p>
This thread was published { $thread->created_at->diffForHumans() } by <a href=”#”>{$thread->creator->name }</a>, and currently
has <span
v-text=”repliesCount”></span> { str_plural(‘comment’, $thread->replies_count) } . </p> <p> <subscribe-button :active=”{ json_encode($thread->isSubscribedTo) }” v-if=”signedIn”></subscribe-button>

<button class=”btn btn-default”
v-if=”authorize(‘isAdmin’)”
@click=”toggleLock”
v-text=”locked ? ‘Unlock’ : ‘Lock’”></button>
</p>
</div>
</div>
</div>
</div>
</div>
</thread-view>
@endsection

And the ThreadView Component doesn’t include <template></template> tag.

Taylor still uses the blade as default and just import Vuejs component when needed.

#2. Component: Same above but all the stuff in view will be brought into <template></template> tag.

Which way should I prefer to use in my project? I can’t see the advantages and disadvantages of both ways. The only thing I can see, if I use the inline-template, I can take advance of Laravel Collection helper or blade directive (@auth, @guest).

### Solution :

I think it depends on the complexity of the interface you intend to implement. Personally, I use Vuejs with the whole of its capabilities as my frontend layer of my application. In this case, you can employ vue.js Router to transform more smoothly between the pages and also Vuex as the storage management in the frontend layer.

To sum up, if you want to implement a SPA (Single Page Application) choose the second way. But if you want to just use limited capabilities of Vuejs continue the first way.

# [Vue.js] How to remove particular marker form google map when user start retype another place name in textbox

I’m trying to remove place marker form map. when user perform keypress event in input field.in my project there is two gmap-autocomplete components the both creat diffrent markers on map.so when i use setMap(null) then it remove all the markes form map.i need to remove one at a time.Please help Thank you.!

refreshMapEndSource(event) {
if (document.getElementById(‘txtDestination’).value != ‘’) {
let endOrigin = document.getElementById(‘txtDestination’).value
if (this.markRemEnd != null) {
if (endOrigin != this.markRemEnd.fplace) {
console.log(‘NOt Equal’)
console.log(this.$google.marker[i].fplace) this.$google.marker[0].setMap(null)
}
}
} else {
//
}
}

### Solution :

I’m not sure what are you trying to do but I guess you want to remove markers which created from either A or B component.

To do this when you create marker you have to keep it in some array let’s call it as markers:

let markers = []

let marker = new google.maps.Marker({
position: location,
map: map
})

markers.push({
type: ‘A’ // or ‘B’,
marker
})

Then whenever you want to remove markers from A:

markers.forEach(marker => {
if (marker.type === ‘A’) marker.marker.setMap(null)
})

markers = this.markers.filter(marker => marker.type !== ‘A’)

Well if my guess is wrong and you really want to remove particular marker which is pretty similar you have to know which marker you have remove.

markers.push({
name: ‘abc’,
marker
})

markers.forEach(marker => {
if (marker.name === ‘abc’) marker.marker.setMap(null)
})

# [Vue.js] How to bind radio buttons to containers using v-for?

there is been trying to build a quiz with vue.js js but am running into the problem right now where the radio buttons are not getting bound to the questions like I want: https://jsfiddle.net/deeformvp/sqx3m2bz/2/

<div v-for=”(question, index) in questions” :key=”index”>
{question.question}
<div v-for=”(answer, index) in question.answers” v-model=”pricingUnit” :key=”index”>
<label>
<input type=”radio” name=”question.question”>{answer}
</label>
</div>
</div>

All the answers seem to be working together instead of separated by question div. What am I missing?

there is taken a look at Vue.js how to use radio buttons inside v-for loop and ensured that I bound the name variable but it still does not work.

### Solution :

You have a typo: name should be :name:

<input type=”radio” :name=”question.question”>

# [Vue.js] how to manage vue reactivity?

I need to update a component after getting data from the data base.
but i get an error message. there is tried v-if and v-show and i had the same result.

the componenet that to update is a modal

<div>
<b-modal id=”modal-xl”
ok-title=”next”
:size=”modalSize”
@ok.prevent=”launchContentModal”
@cancel=”resetPostModal”
hide-header-close
no-close-on-backdrop>
<add-post :postTitle=”postTitle”
:postTopic=”postTopic”
:postType=”postType”>
</add-post>
<add-content v-show=”post.id”
:postType=”postType”>
</add-content>
<ArticlesEditor v-show=” post.id && post.postType.id”>
</ArticlesEditor>
</b-modal>
</div>

and data object is :

data(){
return {
postTitle:’’,
topic:’’,
postTopic:[],
postType: {title: ‘video’,id:1},
user:{},
post:{
id:’’,
postTopic:[],
postType:{
title:’’,
id:’’,
},
},

}

the request method is :

launchContentModal(){
if(!this.postTitle) this.$root.$emit(‘noTitleProvided’);
else if(!this.postTopic[0]) this.$root.$emit(‘noTopicProvided’);
else {
this.post = { title: this.postTitle, topics:this.postTopic, type: this.postType};
ResourceCenter.save(this.department, this.user, this.post)
.catch(({response}) =>alert(response.data))
.then(({data}) => {
this.post = data;
});
}
},

after sending save request ,i get the response correctly,
this is the response object:

{“title”:”sdf”,”client_id”:”12”,”department_id”:”327”,”type”:”ebook”,”type_id”:2,”user_id”:668,”updated_at”:”2019-05-08 09:15:44”,”created_at”:”2019-05-08 09:15:44”,”id”:59} `

and post object after getting the response updates correctly:

post:{“title”:”sdf”,”client_id”:”12”,”department_id”:”327”,”type”:”ebook”,”type_id”:2,”user_id”:668,”updated_at”:”2019-05-08 09:15:44”,”created_at”:”2019-05-08 09:15:44”,”id”:59}

the expected result : modal should be updated and add-content compoenet should be showed.

the error message is :
[vue.js warn]: Error in render: “TypeError: Cannot read property ‘id’ of undefined”

i hope the explanation was clear

### Solution :

There is no post.postType in the response but you are accessing post.postType.id from the template:

<ArticlesEditor v-show=” post.id && post.postType.id”>

Here, post.postType = undefined & trying to access post.postType.id so, the error:

[vue.js warn]: Error in render: “TypeError: Cannot read property ‘id’ of undefined”