How to set all object properties to null in JavaScript? - vue.js

I am using Vue and suddenly some of the computed css using vuetify is not working.
The way I declare an object is
personal_info : {}
and in my template, I could just do personal_info.name and other more in every v-model of text input.
I have no errors but suddenly the vuetify has a class called input-group--dirty that will elevate the label of the text input whenever it's not empty. But suddenly, it's not working. It looks like this:
As you can see, the text and label are overlapping.
The only thing that make it work is to set the property to null which is:
personal_info : {
name: null
}
The problem is that I have hundreds of text inputs and I dont want to set everything to null.
Is there a simple way to set all of the object's properties to null instead of coding it 1 by 1?

checkout this snippet
var personal_info = {
name: 'john',
email: 'john#moto.com',
phone: 9876543210
}
console.log(JSON.stringify(personal_info)); //before looping
for (var key in personal_info ) {
personal_info[key] = null;
}
console.log(JSON.stringify(personal_info));//after looping and setting value to 'null'

Vilas example is ok. But in case you have nested properties and your obj looks like this you could try my snippet
var obj = {
a: 1 ,
b: 2,
c: {
e:3,
b: {
d:6,
e: ['23']
}
}
};
var setProps = function(flat, newVal){
for(var i in flat){
if((typeof flat[i] === "object") && !(flat[i] instanceof Array)){
setProps(flat[i], newVal);
return;
} else {
flat[i] = newVal;
}
}
}
setProps(obj, null);
console.log(JSON.stringify(obj));

you can use simple immutable oneliner:
Object.fromEntries(Object.entries(YOUR_OBJECT).map(([key]) => [key, null])))
const bio = {
name: 'john',
age: 22,
hobbies: ['soccer']
}
const resetBio = Object.fromEntries(Object.entries(bio).map(([key]) => [key, null]))
console.log(bio)
console.log(resetBio)

Related

All values getting upadted when tried to update single element in an associative array in Vue 3

I have the below code in Vue3:
data: function() {
return {
testData:[],
}
},
mounted() {
var testObj = {
name: 'aniket',
lastname: 'mahadik'
}
for (let index = 0; index < 3; index++) {
this.testData.push(testObj);
}
},
methods: {
updateLastName: function(key) {
this.testData[key].lastname = 'kirve';
}
}
When I call updateLastName(1) to update the lastname of only the second element, it's updating the lastname of all the elements.
I tried several ways but found no desired result.
Can someone point out to me what is going wrong here?
It is because you are pushing the reference to the same object in the array so when you update any item in the array you are instead updating every item since it reference the same object.
Either push by cloning the object :
testData.value.push({...testObj})
Or put the definition in the push
testData.value.push({ name: 'aniket', lastname: 'mahadik' })
Is JavaScript a pass-by-reference or pass-by-value language?

In ag grid drop down, how to show name once selected and on save set value instead of name.?

Using this reference, I had worked ag grid drop down.
Issue : once I selected a drop down value, then getvalue() returns value instead of name. Hence it shows the number on the column and it should be text.
If I change that to name, while saving, its bind to name . But here it should be value.
Required : getValue should return name & saving the array should contain value.
agInit(params: any): void {
this.params = params;
this.value = this.params.value;
this.name = this.params.name;
this.options = params.options;
}
getValue(): any {
return this.value;
}
ngAfterViewInit() {
window.setTimeout(() => {
this.input.element.nativeElement.focus();
})
}
stackbltiz here
here
How can I achieve this.
You don't have to create new cellRenderer and cellEditor for it, ag-grid provides inbuilt select for it. **
When you using objects (for dropdown\combobox) inside single cell - you have to implement value handlers: valueParser and valueFormatter:
Value parser: After editing cells in the grid you have the opportunity to parse the value before inserting it into your data. This is done using Value Parsers.
colDef.valueParser = (params) => {
return this.lookupKey(mapping, params.newValue);
}
Value formatter: Value formatters allow you to format values for display. This is useful when data is one type (e.g. numeric) but needs to be converted for human reading (e.g. putting in currency symbols and number formatting).
colDef.valueFormatter = (params) => {
return this.lookupValue(mapping, params.newValue);
}
*where mapping represents your object and inside each of those functions you are just extracting key or value.
Original solution:
lookupValue(mappings, key) {
return mappings[key];
}
lookupKey(mappings, name) {
var keys = Object.keys(mappings);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (mappings[key] === name) {
return key;
}
}
}
and here my little bit modified:
lookupValue(mappings, key:string) {
if(!mappings || !mappings.find(item => item.Id == key)) return null;
else
return mappings.find(item => item.Id == key).Value;
}
lookupKey(mappings, name) {
let key: any;
for (key in mappings) {
if (mappings.hasOwnProperty(key)) {
if (name === mappings[key]) {
return key.Id;
}
}
}
}
UPDATE
To populate dropdown you need yo use cellEditorParams:
colDef.cellEditor = 'selectCellEditor';
colDef.cellEditorParams = {
values: yourList,
},
** But in case when it could be required you still need to have both of renderers and store object inside, and then you would be able to choose what would be displayed on every stage.

How to pass an array values from one function to another function in vuejs?

I am trying to get the array values from
"validateBeforeSubmit" function to "saveForm" function. But I am
getting values of "undefined" in "arrlength". Please help me to solve.
This my code in vue.js
export default {
name: '',
data() {
return {}
},
ready: function() {
this.validateBeforeSubmit()
this.saveForm();
},
methods: {
validateBeforeSubmit() {
var fieldsVal = new Array();
var firstName = document.getElementById('firstName').value
var lastName = document.getElementById('lastName').value
var designation = document.getElementById('designation').value
if (firstName != "" && lastName != "" && designation != "") {
fieldsVal.push(firstName);
fieldsVal.push(lastName);
fieldsVal.push(designation);
return fieldsVal;
} else {
fieldsVal.length = 0;
return fieldsVal;
}
return fieldsVal;
},
saveForm() {
var fieldsValArray = this.validateBeforeSubmit();
var arrLength = fieldsValArray.length;
}
}
}
I can see multiple issues in your code:
1) Don't apply jQuery-like approach for getting input values. Use v-model instead. This will simplify your code
<template>
<input v-model="form.firstName" type="text"/>
</template>
<script>
export default {
data: {
form: {
firstName: '',
}
},
methods: {
validateBeforeSubmit() {
// take `firstName` directly from `data` not need for `getElementById`
const firstName = this.form.firstName;
}
},
}
</script>
2) Remove validateBeforeSubmit and saveForm from ready. Ready hook is obsolete in vue#2. And also it makes no sense. It's better to call it on form #submit.
3) It's better to create array using [] syntax instead of new Array()
Why never use new Array in Javascript
4) Always provide name for your component for easier debug
export default {
name: 'ValidationForm',
}
5) I don't know where was an issue but it works. Check this link below. I have updated your code. Try to submit form and check the console:
https://codesandbox.io/s/w6jl619qr5?expanddevtools=1&module=%2Fsrc%2Fcomponents%2FForm.vue

Cannot format or transform data before save, bound too tightly to the view

I have some data in vuejs that I want to format before sending it off through an ajax call but it changes the view its bound to. For example I have a birthday field that is formatted like this on the view 01/11/1981 but I need to format that to YYYY-MM-DD HH:mm:ss for the db and I don't want to do this on the backend.
Where and when would I do this on the frontend? I have tried doing this before the ajax request and it changes the view, so I made a copy of the data and modified it and that also changed the view. It seems no matter what I do it affects the view.
Here is my methods block:
methods: {
/**
* Update the user's contact information.
*/
update() {
/*Attempt to copy and format*/
var formattedForm = this.form;
formattedForm.birthday = moment(formattedForm.birthday).format('YYYY-MM-DD HH:mm:ss');```
Spark.put('/settings/contact', formattedForm)
.then(() => {
Bus.$emit('updateUser');
});
},
}
Here is my data block as well:
data() {
return {
form: $.extend(true, new SparkForm({
gender: '',
height: '',
weight: '',
birthday: '',
age: '',
}), Spark.forms.updateContactInformation),
};
},
The easiest way is to make a clone using Object.assign, like so:
let form = Object.assign({}, this.form);
form.age = 21;
Here's the JSFiddle: https://jsfiddle.net/y51yuf05/
Objects are passed by reference in javascript, which means:
let a = {
"apple": 6
}
let b = a
then, b and a are pointing to the same location in the memory, it is essentially copying the address of the object in a to the variable b.
You need to therefore clone the object, there are many ways to do it like:
b = Object.assign({}, a)
MDN: Object.assign()
this would not be deeply cloned, which means if your object is nested then the nested objects would still be linked between the original and the copy.
for which I use:
function isObject(obj) {
return typeof obj === 'object' && !Array.isArray(obj)
}
function clone(obj) {
let result = {}
for (let key in obj) {
if (isObject(obj[key])) {
result[key] = clone(obj[key])
} else {
result[key] = obj[key]
}
}
return result
}
function logger () {
console.log("p.a.b.c: ", p.a.b.c)
console.log("q.a.b.c:", q.a.b.c)
console.log("r.a.b.c:", r.a.b.c)
}
let p = {a: {b: {c: 5}}}
let q = clone(p)
let r = Object.assign({}, p)
logger()
p.a.b.c = 11
logger()

In an ExtJS Grid, how do I get access to the data store fields that are part of the sort set

How do I get access to the columns/datastore fields that are part of the sort set.
I am looking to modify the a grid's sort parameters for remote sorting. I need the remote sort param's sort key to match the column's field's mapping property. I need these things to happen though the normal 'column header click sorts the data' functionality.
Remote sorting and field mapping (ExtJS 4.1)
This functionality seems not to be implemented in ExtJS. Here is a solution using the encodeSorters function provided since ExtJS 4. Accessing fields map throught the model's prototype is a bit dirty but it does the job :
var store = Ext.create('Ext.data.Store', {
...,
proxy: {
...,
encodeSorters: function (sorters) {
var model = store.proxy.model,
map = model.prototype.fields.map;
return Ext.encode(Ext.Array.map(sorters, function (sorter) {
return {
property : map[sorter.property].mapping || sorter.property,
direction: sorter.direction
};
}));
}
}
});
However, it would be more relevant to override the original method :
Ext.data.proxy.Server.override({
encodeSorters: function(sorters) {
var min, map = this.model.prototype.fields.map;
min = Ext.Array.map(sorters, function (sorter) {
return {
property : map[sorter.property].mapping || sorter.property,
direction: sorter.direction
};
});
return this.applyEncoding(min);
}
});
Assuming you are using simpleSortMode, you could do something like this in your store.
listeners: {
beforeload: function( store, operation, eOpts ) {
if (store.sorters.length > 0) {
var sorter = store.sorters.getAt(0),
dir = sorter.direction,
prop = sorter.property,
fields = store.model.getFields(),
i,
applyProp = prop;
for (i = 0; i < fields.length; i++) {
if (fields[i].name == prop) {
applyProp = fields[i].mapping || prop;
break;
}
}
//clearing the sorters since the simpleSortMode is true so there will be only one sorter
store.sorters.clear();
store.sorters.insert(0, applyProp, new Ext.util.Sorter({
property : applyProp,
direction: dir
}));
}
}
},