I have props like below
props: ['applicants',],
I would like to use props like below
methods : {
formated (item) {
var _self = this;
_self.values.length = 0;
if(item == "") {
console.log(this.applicants); //I am getting output here
_self.values = this.applicants
}
else {
console.log(this.applicants); //I am not getting output here
this.applicants.filter(applicant => { })
}
}
}
Why it is happening like this?
You don't need to create a reference to this. Assuming this.values is an array:
methods: {
formatted (item) {
this.values = item == "" ? this.applicants : this.applicants.filter(applicant => { })
}
}
Related
I have 1 component to which I pass a computed as a prop in this way:
<Datatable :extraParams="extraParams" />
the computed is in the attached image.
I'm having trouble with the value of this property: coverageSelected:coverageData
Coverage data is filled by a select multiple
The problem I have is that when selecting an element of the select, first the component function is executed, then the coverageSelected property is empty, then the computed is executed and until this moment the coverageSelected array is filled, then until the second attempt It already has a full array.
This is my computed
props: [
"status_selected",
"rows",
"totals",
"dateRangeValue",
"coverageSelected",
"coverageList",
"showAll",
"dateFilterSelected",
],
computed(){
extraParams() {
let coverageData = this.coverageList.filter((m) => this.coverageSelected.includes(m.variable));
return {
status: this.status_selected,
dateRange: this.dateRangeValue,
dateFilterSelected: this.dateFilterSelected,
coverageSelected: coverageData, //This is the property that is not late.
showAll: this.showAll,
};
},
}
Another detail to mention that this.coverageSelected is a prop
The method that is executed first in the computed is this:
async getList(params) {
this.loading = true;
try {
if (params) {
this.query = { ...this.query, ...params, ...this.extraParams, filters: this.filters };
} else {
this.query = { ...this.query, ...this.extraParams, filters: this.filters };
}
const { data } = await this.$axios.post(`${this.$config.routePrefix}${this.action}`, this.query);
if (data.code == 200) {
this.rows = data.rows;
this.total = data.total;
this.$emit("listed", data);
}
} finally {
this.loading = false;
}
},
I have a v-data-table on vue, which gets data and dynamically adds and deltes rows based on the incoming object of arrays, Vue is reactive to adding and deleting but doesn't seem to react to array replace.
My function to add, delete and replace is the setup the following way:
function update_helper(update_obj, dataObject, colObject) {
update_obj.Data.forEach((item) => {
if (typeof item.RowData !== 'undefined'){
let temp_list = updateRow(item, colObject);
temp_list.forEach((row_obj) => {
var found = dataObject.find(Element => Element.RowID === row_obj.RowID);
if (typeof found !== 'undefined'){
//Replace
var found = dataObject.findIndex(Element => Element.RowID === item.RowID);
//console.log(row_obj);
//console.log(dataObject[found]);
dataObject[found] = row_obj;
}
else{
// Add
dataObject.push(row_obj);
}
});
}
else if (typeof item.RowData === 'undefined') {
// Delete
var found = dataObject.findIndex(Element => Element.RowID === item.RowID);
dataObject = dataObject.splice(found, 1);
}
});
}
The function keeps track of the row Id . My replace function dataObject[found] = rowObj works but isn't reactive, i.e the change can only be seen when I switch tabs or refresh the page.
How do I workaround this.
Instead of passing it as argument, you could better have it as a data variable like
data() {
return {
dataObject: [],
}
}
and then define your function inside the methods section like
methods: {
update_helper(update_obj, colObject) {
update_obj.Data.forEach((item) => {
if (typeof item.RowData !== 'undefined'){
let temp_list = updateRow(item, colObject);
temp_list.forEach((row_obj) => {
var found = dataObject.findIndex(Element => Element.RowID === row_obj.RowID);
if (found !== -1){
this.dataObject[found] = row_obj;
}
else{
// Add
this.dataObject.push(row_obj);
}
});
}
else if (typeof item.RowData === 'undefined') {
// Delete
var found = this.dataObject.findIndex(Element => Element.RowID === item.RowID);
dataObject = this.dataObject.splice(found, 1);
}
});
}
}
If possible you can declare the colObject also in the data() section
Note: If you observe the above function body, I would have accessed the dataObject using this operator.
I am using a computed property diameter() to return either:
- a random number (randomise: true)
- a number returned from an object within an array (randomise: false).
I do have a working implementation (see bottom of post) but would like to know why the cleaner implementation doesn't work. With randomise: false, diameter() returns undefined. Why?
vars [
{varName: diameter, varValue: 25.8},
{varName: quantity, varValue: 68}
]
computed: {
diameter() {
if (randomise) {
return math.randomInt(100, 1000) //no problems
} else {
console.log(this.populateValue('diameter')) //undefined
return this.populateValue('diameter')
}
}
}
methods: {
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
console.log(element.varValue) //25.8
return element.varValue
}
})
}
}
The following implementation works but why do I have to create an arbitrary property to do so?
diameter() {
if (!this.vars || !this.passVars) {
return math.randomInt(100, 1000) / (10 ** math.randomInt(0, 3))
} else {
this.populateValue('diameter')
return this.blah
}
}
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
this.blah = element.varValue
}
})
}
The problem is that return element.varValue is returning from the forEach, not populateValue.
There are various ways to write this. e.g.
for (const element of this.vars) {
if (element.varName === variableName) {
return element.varValue
}
}
By using a for/of loop there is no inner function so the return returns from the function you're expecting.
Alternatives include:
let value = null
this.vars.forEach(element =>
if (element.varName === variableName) {
value = element.varValue
}
})
return value
or:
const match = this.vars.find(element =>
return element.varName === variableName
})
if (match) {
return match.varValue
}
I have defined the data like this
data() {
return {
mdrender: '',
markdown: ''
};
},
And I have this function :
methods: {
interpretVars: function(markdown) {
$.getJSON("/api/v1/getdoc?code=" + this.$route.query.code, function (result) {
var interpreted = markdown.replace(/\{\#(companyName)\#\}/g, 'Demo')
.replace(/\{\#(docType)\#\}/g, result[0].datas.category).replace(/\{\#(version)\#\}/g, result[0].datas.version)
.replace(/\{\#(docTitle)\#\}/g, result[0].datas.title);
this.markdown = interpreted;
console.log(interpreted);
return interpreted;
});
}
},
Now the problem is that the markdown data value does not take the new value, while the variable that I'm console logging interpreted have the correct value.
I'm doing something wrong?
Thanks in advance for replying.
Your problem is the use of the function() statement. So you will loose the scope and this doesn't represents to the current Vue instance. There are two possible solutions to fix this:
Use an arrow function:
methods: {
interpretVars: function(markdown) {
$.getJSON("/api/v1/getdoc?code=" + this.$route.query.code, (result) => {
…
});
}
},
Use a helper variable:
methods: {
interpretVars: function(markdown) {
var $this = this;
$.getJSON("/api/v1/getdoc?code=" + this.$route.query.code, function (result) {
…
$this.markdown = interpreted;
});
}
},
I guess the best way of doing this would be doing it like this :
methods: {
async interpretVars(markdown) {
$.getJSON("/api/v1/getdoc?code=" + this.$route.query.code, function (result) {
var interpreted = markdown.replace(/\{\#(companyName)\#\}/g, 'Demo')
.replace(/\{\#(docType)\#\}/g, result[0].datas.category).replace(/\{\#(version)\#\}/g, result[0].datas.version)
.replace(/\{\#(docTitle)\#\}/g, result[0].datas.title);
this.markdown = interpreted;
console.log(interpreted);
return interpreted;
});
}
This should work as expected i guess, please don't assign this to temp variable.
Store this scope variable to a temporary variable and use that variable.
methods: {
interpretVars: function(markdown) {
let that = this;
$.getJSON("/api/v1/getdoc?code=" + this.$route.query.code, function (result) {
var interpreted = markdown.replace(/\{\#(companyName)\#\}/g, 'Demo')
.replace(/\{\#(docType)\#\}/g, result[0].datas.category).replace(/\{\#(version)\#\}/g, result[0].datas.version)
.replace(/\{\#(docTitle)\#\}/g, result[0].datas.title);
that.markdown = interpreted;
console.log(interpreted, that.markdown);
return interpreted;
});
}
},
I am trying to find simple way to update the form fields with Validators. For now I do the below:
ngOnInit() {
this.form.get('licenseType').valueChanges.subscribe(value => {
this.licenseChange(value);
})
}
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.form.get('price').setValidators([Validators.required]);
this.form.get('price').updateValueAndValidity();
this.form.get('noOfLicenses').setValidators([Validators.required]);
this.form.get('noOfLicenses').updateValueAndValidity();
this.form.get('licenseKey').setValidators([Validators.required]);
this.form.get('licenseKey').updateValueAndValidity();
this.form.get('supportNo').setValidators([Validators.required]);
this.form.get('supportNo').updateValueAndValidity();
this.form.get('purchasedFrom').setValidators([Validators.required]);
this.form.get('purchasedFrom').updateValueAndValidity();
//......others follows here
}
else {
this.form.get('price').clearValidators(); this.form.get('price').updateValueAndValidity();
this.form.get('noOfLicenses').clearValidators(); this.form.get('noOfLicenses').updateValueAndValidity();
this.form.get('licenseKey').clearValidators(); this.form.get('licenseKey').updateValueAndValidity();
this.form.get('supportNo').clearValidators(); this.form.get('supportNo').updateValueAndValidity();
this.form.get('purchasedFrom').clearValidators(); this.form.get('purchasedFrom').updateValueAndValidity();
//......others follows here
}
}
Is this the only way to add and update validators or is there any other way to achieve this. For now I am calling the updateValueAndValidity() after setting/clearing each field.
Update
Something like
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.form.get('price').setValidators([Validators.required]);
//......others follows here
}
else{
//......
}
}
this.form.updateValueAndValidity();///only one line at the bottom setting the entire fields.
I done something similar like this
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.updateValidation(true,this.form.get('price'));
//......others follows here
}
else {
this.updateValidation(false,this.form.get('price'));
//......others follows here
}
}
//TODO:To update formgroup validation
updateValidation(value, control: AbstractControl) {
if (value) {
control.setValidators([Validators.required]);
}else{
control.clearValidators();
}
control.updateValueAndValidity();
}
If you want to do this for all the controlls inside your form
licenseChange(licenseValue: any) {
for (const field in this.form.controls) { // 'field' is a string
const control = this.form.get(field); // 'control' is a FormControl
(licenseValue === 2) ? this.updateValidation(true,
control):this.updateValidation(fasle, control);
}
}
I did it like below:
this.form.get('licenseType').valueChanges.subscribe(value => {
this.licenseChange(value, this.form.get('price'));
//....Others
}
licenseChange(licenseValue: any, control: AbstractControl) {
licenseValue === 2 ? control.setValidators([Validators.required]) : control.clearValidators();
control.updateValueAndValidity();
}