Click handler on v-for loop in vue3 not showing up in the DOM - vuejs3

I have run into a roadblock on a project where everything seems to be working fine except that I can't seem to add a click handler on a v-for loop object.
Here's the demo code that is structured very similarly to my original code
<template>
<article>
<a
v-for="(post, index) in posts"
:key="index"
target="_blank"
#click="alert(post.title)"
>
<figure >
<img
:src="post.source_url"
:alt="post.title"
/>
<figcaption>{{ (post.title) }}</figcaption>
</figure>
</a>
</article>
</template>
<script setup>
const posts = [
{
title:"abc",
content:"defg",
source_url:"https://unsplash.it/200/100",
},
{
title:"uvw",
content:"xyz",
source_url:"https://unsplash.it/150/101",
}
]
</script>
Here's the link to codepen as well..
https://codepen.io/alimbolar/pen/XWBzgVX
The console.log shows this error on codepen..
"[Vue warn]: Unhandled error during execution of native event handler" "
" " at <Pen>"
but on my original code there's no error on localhost.. it's just that the click handler is just not appearing in the dom..
I would appreciate some guidance on what I am doing wrong as I seem to have tried everything and I know maybe it's something very very basic that I am missing.. please advise.
Regards,
Alim

That's just a warning. The real error is given in the console right after:
Uncaught TypeError: _ctx.alert is not a function
The context of inline handlers is not the same as window. You need to call the alert function from a method in your component script.
#click="showAlert(post.title)"
const showAlert = (title) => {
alert(title)
}
updated codepen

Related

Using pick in array Nuxt 3 useFetch

I'm trying to replicate the nuxt 3 useFetch sample but no luck so far.
https://v3.nuxtjs.org/getting-started/data-fetching#usefetch
My post.vue page contains the below code:
<template>
<section>
<div v-for="mountain in mountains" :key="mountain">{{mountain}}</div>
</section>
</template>
<script setup>
const runtimeConfig = useRuntimeConfig()
const { data: mountains, pending, error, refresh } = await useFetch('/mountains',{
baseURL: runtimeConfig.public.apiBase,
pick: ['title']
})
console.log(mountains.value)
</script>
For some reason the data is not shown in template.
The console.log() shows Proxy {title: undefined}
I've realized that removing the pick option solves the issue, so I'm wondering if pick only works for objects and can't be used in arrays.
It's odd because the sample is using an array https://v3.nuxtjs.org/api/composables/use-fetch.
The pick option currently works only if you are fetching one document (one Js object).
In the official docs you can see they are fetching a specific document in their API: https://nuxt.com/docs/getting-started/data-fetching.
One option you have is to make an API route that returns one object only.
Inside of your <div>, you are trying to return {{mountain}}, but at the time this page loads there is no such variable--because the const mountains hasn't been fetched yet. What you need to do is add a <div v-if="mountains" v-for="mountain in mountains" :key="mountain">{{mountain}}</div>
For the brief moment it takes before the useFetch function to return mountains,the <div> will not try to show {{mountains}}, because the v-if prevents the <div> from being shown in the first place.

How do I fix the following error: "Cannot read property 'init' of undefined"?

I am running Meteor release METEOR#1.4.2.3
I recently installed a social media share package via Atmosphere.
meteor add ellisonleao:sharerjs.
More information about the package can also be found at:
http://www.ellison.rocks/sharer.js/
My template event handler looks like this:
Template.detail.events({
"click .sharer": function() {
//add new buttons with share behaviour
$('.postedImagesWell').append(<button class="sharer button" data-sharer="facebook" data-url="https://ellisonleao.github.io/sharer.js/">Share on Facebook</button>);
window.Sharer.init();
}
});
Find below the template in code:
<template name="detail">
<div class="postedImagesWell">
<img class = "img-responsive img-rounded postedImages" id = "trial" src="{{this.photo.url}}" alt="thumbnail" >
</template>
when I run click on the Share on Facebook link. I see this error message in my browser:
Uncaught TypeError: Cannot read property 'init' of undefined
Any help on how to resolve the issue would be great!
Thanks in advance
You should try the other repo listed on the atmosphere page of this lib: https://github.com/okmttdhr/sharer.npm.js
Also, I don't think you need to append the share button with jquery. Just add the button to your template, and on the click listener, instead of calling window.Sharer, you add the event parameter to the listener function then instantiate a new sharer, like this:
import Sharer from 'sharer.npm.js';
// ...
Template.detail.events({
"click .sharer": function(event) {
const sharer = new Sharer(event.target);
sharer.share();
}
});

how to attach multiple events to a ractive element

The documentation describing method call event handling suggests that it's possible to attach multiple handlers to an event separated by a comma, like this:
<p on-click='speak(), bark()'>{{name}}</p>
However this throws an error when the element is first rendered, so clearly I'm misunderstanding the docs. Can someone please help me to understand how to attach multiple handlers to the on-click event.
thanks in advance
Les
I believe you're still using 0.7 or older. Update to the latest version (0.8.7 as of this writing) and you'll be able to do the following:
const Component = Ractive.extend({
template: `
<button on-click="#this.foo(), #this.bar()">Click Me</button>
`,
foo(){
alert('Hello')
},
bar(){
alert('World!')
}
});
new Component({ el: 'body' });

Meteor Iron:Router Template not Rendering

I have a main page which lists a few text items ("Ideas"), which are clickable links. Clicking on them should take you to a page where you can edit them. Here's my html:
<head>
<title>Ideas</title>
</head>
<body>
</body>
<template name="Ideas">
<ul>
{{#each ideas}}
{{> idea}}
{{/each}}
</ul>
</template>
<template name="idea">
<li>{{text}}</li>
</template>
<template name="ShowIdea">'
<div class="editable" contentEditable="true">{{text}}</div>
</template>
I've added Iron:Router to my project to allow for moving between the pages. Here's the javascript:
Ideas = new Mongo.Collection("ideas");
if (Meteor.isClient) {
Router.route('/', function() {
this.render('Ideas');
});
Router.route('/idea/:_id', function() {
var idea = Ideas.findOne({_id: this.params._id});
this.render('ShowIdea', {text: idea.text});
});
Template.Ideas.helpers({
ideas: function () {
return Ideas.find({});
}
});
}
I inserted a single idea to my Mongo DB using the Meteor Mongo command line tool. That single item shows up properly on my main page. Here's what the HTML looks like in my debugger for the main page:
<html>
<head>...</head>
<body>
<ul>
<li>
The first idea ever
</li>
</ul>
</body>
</html>
Clicking on that link takes me to a new page with an address of:
http://localhost:3000/idea/ObjectID(%22550b7da0a68cb03381840feb%22)
But nothing shows up on the page. In the debugger console I see this error message + stack trace, but it means nothing to me since it all seems to be pertaining to iron-router and meteor, not code which I actually wrote:
Exception in callback of async function: http://localhost:3000/Idea.js?2fd83048a1b04d74305beae2ff40f2ea7741d40d:10:44
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
onRerun#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:520:13
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
onRun#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:505:15
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
dispatch#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:448:7
_runRoute#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:543:17
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:844:27
route#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:710:19
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:371:18
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
dispatch#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:448:7
http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:390:21
_compute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:308:36
Computation#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:224:18
autorun#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:499:34
http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:388:17
nonreactive#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:525:13
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:387:19
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1688:22
onLocationChange#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1772:33
_compute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:308:36
_recompute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:322:22
flush#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:452:24
And then it ends with this warning message:
Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction?
I don't have an onBeforeAction (I'm not even sure what that is)... so I don't think that message pertains to me?
I just started using Meteor the other day and just added iron-router not 24 hours ago, so I'm a bit lost here. Any pointers on how I can debug and fix this would be great.
Two things need fixing:
When you insert documents from the shell they are assigned _id values which are mongo ObjectIDs, whereas meteor defaults to using strings. This explains the weird URL. To avoid this problem, it's generally best to initialize your data from the server. Here's an example:
if (Meteor.isServer) {
Meteor.startup(function() {
if (Ideas.find().count() === 0) {
Ideas.insert({text: 'feed the cat'});
}
});
}
Now after a $ meteor reset you will always start with one cat-related idea.
If you wish to pass a context to your template, you'll need to use the data attribute like so:
Router.route('/idea/:_id', function() {
this.render('ShowIdea', {
data: function () {return Ideas.findOne({_id: this.params._id})}
});
});
See this example from the docs. After making those changes, the code worked correctly for me.

aria.touch.swipeend event issue--not working as expected

I am trying to use swipe events to obtain iphone like toggle switch. i want to handle swipemove and swipeend events. For example:
<div class="xyz" {on swipemove {fn:"swipemoveHandler"} /}> </div>
is working as expected while,
<div class="xyz" {on swipeend {fn:"swipeendHandler"} /}> </div>
is throwing error "The event type: 'swipeend' is an invalid event type."
I am using AT1.3.7 and any help in this regard is greatly helpful.
Thanks in Advance
You can use 'swipe' event of Aria templates which is triggered after a swipe is completed.
Please refer to sample below. This was included in AT 1.3.4
swipeHandler : function (event) {
event.preventDefault(true);
document.getElementById("touchMe").style.visibility = "hidden";
document.getElementById("swipeDirection").innerHTML = event.direction;
document.getElementById("swipeDistance").innerHTML = event.distance;
document.getElementById("swipeLength").innerHTML = event.duration;
document.getElementById("swipeStartX").innerHTML = event.startX;
document.getElementById("swipeStartY").innerHTML = event.startY;
document.getElementById("swipeEndX").innerHTML = event.endX;
document.getElementById("swipeEndY").innerHTML = event.endY;
return false;
}
Below you can see how event can be attached to an element
<div id="touchboard"
{on swipe {
fn : this.swipeHandler,
scope : this
}/}
>
<!-- your content -->
</div>
Refer to link for more help http://snippets.ariatemplates.com/samples/github.com/ariatemplates/documentation-code/samples/utils/touch/swipe/

Resources