How do I clear this error stating that Invalid click event - vue.js

Editorial.vue;
<templates>
<div class="col offset-2">
<router-link to="editorial">
<base-button type="info" #click="saveUserData">Save</base-button>
</router-link>
</div>
</templates>
data() {
return {
userdetails: {
logoURL: null
}
}
},
methods: {
saveUserData: function () {
let formData = new FormData()
formData.append('logoURL', this.userdetails.logoURL)
this.api.uploadFile('editorial/'+store.state.journalId+'/editorialimage'
,formData'journals/v1/').then((res) => {
this.userdetails.journalId = store.state.journalId
this.userdetails.imageId = res.data.status
this.createNewMember()
}, (err) => {
console.log(err)
})
},
When I click save button I'm getting the below error
"Invalid handler for event "click": got undefined
found in
---> <BaseButton> at src/components/BaseButton.vue
<RouterLink>
<Card> at src/components/Cards/Card.vue
<Anonymous>
<ZoomCenterTransition>
<DashboardLayout> at src/pages/Layout/DashboardLayout.vue
<App> at src/App.vue
<Root>"
"I'm getting the above error I don't the solution, the function name also mentioned correctly but still I'm getting the same error. Searched some of the solution but nothing worked. The function posting some data to the server but while clicking the button getting the error". Tried lots of ways to solve this but its all failed.
"I'm getting the above error I don't the solution, the function name also mentioned correctly but still I'm getting the same error. Searched some of the solution but nothing worked. The function posting some data to the server but while clicking the button getting the error". Tried lots of ways to solve this but its all failed.

What is that base-button? if that a custom component, you need to define emit event from the component, so the parent can catch the event and fire the saveUserData function
you might be want to provide some information about your custom component
here some detail how to use emit
https://vuejs.org/guide/components/events.html

Related

Why I'm Facing the error [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"

This is a Laravel & Vue Js Project.
Everything works fine but why I'm facing [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined" type error.
My Vue File
<template>
<p>Sold By: {{product.user.name}}</p>
</template>
<script>
export default {
data(){
return {
product:{},
}
},
methods: {
loadData(){
axios.get('/api/'+this.$route.params.slug+'/product')
.then(response => {
this.product = response.data;
},
()=> {});
}
},
created(){
this.$Progress.start();
this.loadData();
this.$Progress.finish();
},
}
</script>
My Controller
public function getProduct($slug)
{
$product = Product::where('slug',$slug)->with('brand','category','subCategory','productImages','featureDescriptions','colors','variants','user')->first();
return response()->json($product, 200);
}
``
Now I want to show my User name in Vue file <p>Sold By: {{product.user.name}}</p>. It showing User Name With an error [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined". when I show the user data <p>Sold By: {{product.user}}</p>, It show user all data without error. Now how i show user name without error.
The error is self-explanatory: you're using {{product.user.name}} in the template. But before the product has returned from BE, product.user is undefined and therefore does not have a .name property.
The simplest fix would be to place a v-if on the <p>:
<p v-if="product.user">Sold By: {{product.user.name}}</p>
Another generic solution for this type of problem is to use a computed:
<template>
<p>Sold By: {{productUserName}}</p>
</template>
<script>
export default {
// ...
computed: {
productUserName() {
return this.product.user?.name || '';
}
}
// ...
}
</script>
You can read more about optional chaining operator (used above) (?.) here.
Because it's a fairly new addition to JavaScript, Vue doesn't currently support it in <template> tags (but it works in <script>).
Additional note: a common mistake is to add an additional data member instead of using the source of the error (product.user in this case) either directly or through a computed. This creates two problems:
it decouples product.user from rendering the <p>. Which means that if BE returns a product without a user, you'll still get the error, because you've set dataLoaded to true but the template still tries to read the property .name of user, which is falsy and therefore does not have a .name.
you create unnecessary boilerplate: anyone trying to understand or modify your code at a later time has to figure out the arbitrary connection between dataLoaded and product.user.
One of the reasons Vue is loved for is because it doesn't require boilerplate code, unlike other frameworks (i.e: Angular). Keep it that way! By using v-if="product.user" in the template, someone reading that code will immediately understand the rendering logic, without having to look at the component code. Decreasing the time needed to figure out the code on a regular basis will greatly decrease the time needed to modify it, should you (or someone else) ever need to. This results into more flexible, more scalable code. Less bugs, less time spent => more money.
This is happening because <p> is being rendered while product is still an empty object (product: {}).
You could use v-if to render only if product already has been loaded.
<template>
<p v-if="dataLoaded">Sold By: {{ product.user.name }}</p>
</template>
<script>
export default {
data() {
return {
product: {},
dataLoaded: false,
};
},
methods: {
loadData() {
axios.get("/api/" + this.$route.params.slug + "/product").then(
(response) => {
this.product = response.data;
this.dataLoaded = true;
},
() => {}
);
},
},
created() {
this.$Progress.start();
this.loadData();
this.$Progress.finish();
},
};
</script>

(NUXT) How to add component in sweet alert 2

I tried to add a component in swal by the following method.
this.$swal({ html: '<Card :assignment="{}"></Card>' })
But it ends up giving me this error,
error: The "Card" component has been registered but not used vue/no-unused-components
Any leads will be appreciated
The error you're receiving is just a linting error being thrown. It's being thrown because the linter expects you to use the Card component inside the tags.
Try the following:
// inside your Vue component
components: {
// eslint-disable-next-line vue/no-unused-components
Card
}

VeeValidate v3: How to handle backend validation messages?

I am working on upgrading from VeeValidate v2 to v3. Since they have removed the ErrorBag concept, I am struggling to figure out how to handle backend validation.
Previously (see code below), I was just running client-side validation, if that passed, call a server validation route, if that failed I would just use the errors.add function in VeeValidate.
Any help would be appreciated. Just need to know to accomplish backend validation handling in VeeValidate v3. Thanks!
validateStep(step) {
this.$validator.validateAll(step).then((result) => {
// If client-side validation passes, move into this block.
if (result) {
// Then run server-side validation.
axios
.post(`/ajax/validate-stuff`, this.postData)
// If server-side validation Passes:
.then(function (response) {
// Do the things
})
// If server-side validation Fails:
.catch(function (error) {
// Add errors to VeeValidate Error Bag
var entries = Object.entries(error.response.data.errors);
entries.forEach(function(item, index) {
this.Errors.add({
field: item[0],
msg: item[1][0]
});
});
});
}
});
}
The answer by fylzero above is correct. The important point is to ensure that the vid in the validation provider (below it is 'testinput') matches the key in the error object returned by the server. You then catch the error:
<validation-observer v-slot="{ invalid }" ref="formValidator">
<form>
<validation-provider
v-slot="{ errors }"
vid="testinput"
>
<input />
<span>{{ errors[0] }}</span>
</validation-provider>
</form>
</validation-observer>
<script>
try {
// Make the api call here
}
catch (error) {
// populate the vee-validate error manually
this.$refs.formValidator.setErrors(error.data.errors);
}
</script>
I also posted an issue for this in the Github for VeeValidate and was provided the answer.
The documentation for this is, at the time of writing this, buried in the examples section:
https://logaretm.github.io/vee-validate/examples/backend.html#server-side-rules
I was told this will be updated in the proper documentation shortly.
Updated Link: https://vee-validate.logaretm.com/v3/advanced/server-side-validation.html#handling-backend-validation

Handle Vue render errors locally

I am using Vue (server side rendered) with mjml to generate emails.
So I have something (overly simplified) like:
<mjml><mj-body>Hello {{ User.Name }}</mj-body></mjml>
If the model doesn't define User then Vue throws an error and the whole output is lost.
What I want to the output to be along the lines:
<mjml><mj-body>Hello <error>'User' is undefined</error></mj-body></mjml>
I have implemented Vue.config.errorHandler but that just tells me about the error -- there is no rendered output.
Anyway to implement the equivalent of an error handler around each variable substitution?
If you are using Vue version >= 2.5, you can use errorCaptured to create an ErrorBoundary
const ErrorBoundary = {
name: 'ErrorBoundary',
data: () => ({
error: false,
msg: ''
}),
errorCaptured (err, vm, info) {
this.error = true
this.msg = `${err.stack}\n\nfound in ${info} of component`
},
render (h) {
return this.error
? h('pre', this.msg)
: this.$slots.default[0]
}
}
and use this in your component
<error-boundary>
<mjml><mj-body>Hello {{ User.Name }}</mj-body></mjml>
</error-boundary>
If the application has any javascript error, it will be displayed on UI
Example on codepen
If you want to have more user-friendly error, you can customize ErrorBoundary to have fallback to another component. You can find out in this tutorial
Another good example of using errorHandler

VueJS 2 - KeyUp doesn't work

I use Vuetify to generate input field with:
<v-text-field
label="Search"
v-model="search"
#keyup.enter="search()"
required
></v-text-field>
I want I can key up enter to search from this field:
search () {
alert('test')
}
When I key up on enter key, this method doesn't executed...
Make sure you use your developer console for debugging so you can see what error messages you are getting:
Windows: ctrl+shift+I
Mac: ⌘+Option+I
The problem you are actually having here is that you have declared search as a data property and as a method, so you should see the following message:
[Vue warn]: Method "search" has already been defined as a data property.
To fix this change you method name or your data property name:
new Vue({
el: '#app',
methods: {
search() {
alert('search')
},
},
data: {
searchTerm: ''
}
})
And you should find it works fine.
Here's the JSFiddle: https://jsfiddle.net/er9wsfcy/
I had the same issue and everything was in order, turns out the Browser that i was using was the one with issues.
You can try viewing your console from a different browser eg Chrome.
Maybe this might help someone;