Vuelidate - Do not mutate vuex store state outside mutation handlers - vue.js

I am validating a vue form with Vuelidate and I am getting the following error when trying to edit it:
Error: [vuex] do not mutate vuex store state outside mutation handlers.
This is my form input structure:
<hp-text-input
id="company-name"
v-model.trim="$v.formData.companyName.$model"
:code="$v.formData.companyName.$model"
:v="$v.formData.companyName"
:disabled="formData.loading"
:labeltext="$t('components.add_address_modal.company')"
name="company-name"
></hp-text-input>
This is my state:
data() {
return {
formData: {
country: 'Ireland',
address: '',
addressAdditional: '',
addressType: '',
city: '',
companyName: '',
firstName: '',
lastName: '',
zipCode: '',
},
}
},
These are my Vuelidate validations:
validations() {
return {
formData: {
country: {},
address: { required, max: maxLength(32) },
addressAdditional: { max: maxLength(32) },
addressType: { required },
city: { required },
companyName: {},
firstName: { required },
lastName: { required },
zipCode: { required, max: maxLength(10), zipValidate },
},
}
},
I do use a vuex store in this component but it is not even related to the form data itself.
The only thing that worked to get rid of the error for now was creating a copy of the formData and passing it to the form, which for me doesn't make any sense to do.
Do you have any suggestions?

Related

watcher not working to change to lowercase

I am trying to change the users input to lowercase. I know this looks wrong but when I try and type this.email or this.name for the watch it obviously does not work. the v-model is this.email/name accordingly.
What do I need to correct on this
data() {
return {
form: this.$inertia.form({
name: '',
email: '',
password: '',
password_confirmation: '',
birthdate: '',
user_latitude: '',
user_longitude: '',
user_city: '',
user_region: '',
user_country: '',
terms: false,
}),
address: "",
user_address: [],
}
},
watch: {
email(newVal) {
this.form.email = this.form.email.toLowerCase()
},
name(newVal) {
this.form.name = this.form.name.toLowerCase()
}
},
You could try to watch the property path :
watch: {
'form.email'(newVal) {
this.form.email = this.form.email.toLowerCase()
},
or a filter .

Method "watch" has type "object" in the component definition. Did you reference the function correctly? [duplicate]

This question already has an answer here:
VueJS | Method "watch" has type "object" in the component definition
(1 answer)
Closed 1 year ago.
I'm building a Dropdown Component, and Vue is throwing me the following error:
Method "watch" has type "object" in the component definition. Did you reference the function correctly?
watch: {
selected: function (val) {
console.log("value changed", val);
},
}
I've done some research but I can't figure out how to correctly resolve this error, as it appears correct to me, let me know if I should attach some more relevant code. I'll attach my full methods below:
methods: {
updateSelectedValue: function (newValue) {
this.selected = newValue;
},
addParam() {
this.addFormFields(['params'], {
slug: '',
name: '',
isRequired: true,
description: '',
typeSlug: '',
});
},
deleteParam(idx){
this.removeFormFields(['params', idx]);
},
restoreParam(idx){
this.restoreFormFields(['params', idx])
},
$newObject() {
return {
slug: '',
name: '',
isAbstract: false,
requester: '',
description: '',
status: 'inactive',
params: [],
selected: '',
};
},
$extraPrams() {
return {
parentId: this.parentId,
};
},
watch: {
selected: function (val) {
console.log("value changed", val);
},
}
},
};
it seems that you put watch in methods. it should be out of methods

Data not being passed from Child Data to Parent Props

I have a Request Form Component, and within this request form Component I have a Dropdown Menu Component, which I will link both below. All values in my table are pushed into an object upon hitting the Submit Button. However my dropdown selection is only being picked up by my console.log and not being pushed into the Object.
I'm not so familiar with Vue, so I'm not sure what direction to go in for fixing this. I'll attach the relevant (?) pieces of code below.
Parent Component:
<SelectComponent :selected="this.selected" #change="updateSelectedValue" />
export default {
fullScreen: true,
name: 'CcRequestForm',
mixins: [BaseForm],
name: "App",
components: {
SelectComponent,
},
data() {
return {
selected: "A",
};
},
props: {
modelName: {
default: 'CcRequest',
},
parentId: {
type: Number,
default: null,
},
},
mounted() {
this.formFields.requester.value = this.currentRequesterSlug;
},
destroyed() {
if (!this.modelId) return;
let request = this.currentCcRequest;
request.params = request.params.filter(p => p.id)
},
computed: {
...mapGetters(['ccTypesForRequests', 'currentRequesterSlug', 'currentCcRequest']),
ccTypesCollection() {
return this.ccTypesForRequests.map((x)=>[x.slug, this.t(`cc_types.${x.slug}`)]);
}
},
methods: {
addParam() {
this.addFormFields(['params'], {
slug: '',
name: '',
isRequired: true,
description: '',
typeSlug: '',
selected: ''
});
},
deleteParam(idx){
this.removeFormFields(['params', idx]);
},
restoreParam(idx){
this.restoreFormFields(['params', idx])
},
$newObject() {
return {
slug: '',
name: '',
isAbstract: false,
requester: '',
description: '',
status: 'inactive',
params: [],
selected: ''
};
},
$extraPrams() {
return {
parentId: this.parentId,
};
},
updateSelectedValue: function (newValue) {
this.selected = newValue;
},
},
watch: {
selected: function (val) {
console.log("value changed", val);
},
},
};
Child Component:
<script>
export default {
name: "SelectComponent",
props: {
selected: String,
},
computed: {
mutableItem: {
get: function () {
return this.selected;
},
set: function (newValue) {
this.$emit("change", newValue);
},
},
},
};
You have to define the emit property in the parent component, or else it won't know what to expect. That would look like:
<SelectComponent :selected="this.selected" #update-selected-value="updateSelectedValue" />
Check out this tutorial for more information: https://www.telerik.com/blogs/how-to-emit-data-in-vue-beyond-the-vuejs-documentation
To update selected property inside the object, in this constellation, you need to update object property manually upon receiving an event, inside of updateSelectedValue method. Other way could be creating a computed property, since it's reactive, wrapping "selected" property.
computed: {
selectedValue () {
return this.selected
}
}
And inside of object, use selectedValue instead of selected:
return {
...
selected: selectedValue
}

Vue Error: Invalid prop: type check failed for prop "participants". Expected Object, got Array

I'm attempting to pass data from my Parent Component to my Child Component.
Parent Component:
export default {
props: {
bordered: true,
striped: true,
participants:
{
primaryAlias : '',
primaryEmail : '',
primaryAddress : '',
primaryPhone: '',
}
},
Child Component:
export default {
props: {
participants: [
{
type: Object,
value: ''
},
]
},
However, I'm running into many prop errors. Currently I receive the error in my Child Component:
Vue Error: Invalid prop: type check failed for prop "participants". Expected Object, got Array
However, when I attempt to rectify it like this:
export default {
props: {
participants: [
{
type: Object,
value: ''
},
]
},
I receive the following error, again in child component.
Invalid prop type: "[object Object]" is not a constructor
I've tried rewriting many times, but nothing seems to work, happy to hear tips.
update like below then hope solve the issue
when participants is object type:
export default {
props: {
participants:
{
type: Object,
default: {}
},
},
when participants is array type:
export default {
props: {
participants:
{
type: Array,
default: []
},
},
you can read more from here

Accessing validation property outside the current scope in vuelidate/VueJS?

Given the following component in Vue 2 using vuelidate from property validation:
<template>
// template stuff here...
</template>
<script>
import { validationMixin } from "vuelidate";
import { required, requiredIf } from "vuelidate/lib/validators";
export default {
name: "ParentComponent",
mixins: [validationMixin],
data() {
return {
selected: false,
user: {
email: null,
password: null,
},
};
},
validations: {
selected: { required },
user: {
email: { required: requiredIf((vm) => vm.selected) },
password: { required: requiredIf((vm) => vm.selected) },
},
},
};
</script>
The properties user.email and user.password are required, but only if the validation for selected passes successfully. However, this approach does not seem to work, probably because selected is not part of the user validation object.
Is there a way to access this validation property? Something like this...
validations: {
selected: { required },
user: {
email: { required: requiredIf((vm) => vm.$parentVm.selected) },
password: { required: requiredIf((vm) => vm.$parentVm.selected) },
},
},
Just like that. Demo https://codesandbox.io/s/green-darkness-90fjs.
requiredIf good solution for resolve this problem