How can I manipulate key name in Object with Javascript - javascript

I want to do change the name of a key in an Object. But when I want to do this with an if condition, I get this (Assignment to function parameter 'key') error. How can i manipulate a key name ?
My Code:
const personData = [];
Object.keys(testItem).forEach((key) => {
item = testItem[key];
if (key === 'Name'){
key = 'Person Name';
}
personData.push({ name: key, data: Object.values(item) })
});
testItem data:
testItem = {Name: {...}, Surname: {...}}
I want the Name key to change to Person Name without error.

The key variable was taken in as input for the foreach function, and you shouldn't modify it - it is meant as a read only variable. An alternative that doesn't modify the key variable would be
const personData = [];
Object.keys(testItem).forEach((key) => {
let newKey = key;
item = testItem[key];
if (key === 'Name'){
newKey = 'Person Name';
}
personData.push({ name: newKey, data: Object.values(item) })
});

I didn't get what you wanted to do, simply assign keys value to new key and delete previous one for example :
const personData = {
Name: 'John',
lastname: 'Doe'
};
personData.PersonName = personData.Name
delete personData.Name;
console.log(personData.PersonName)

Related

Conditional adding object property in JavaScript

axios.post('saveUser', {id, name})
If name is empty how could I exclude it in the param? if I put ({id, name}), isn't the method would still have a property of name undefined?
I don't want this
const obj = {id: 123, name: undefined}
I want this const obj = {id: 123}
but I don't want to create a temporary variable like so
let obj = { id: id }; if(name) obj = { ...obj, name };
I would suggest you adding object properties conditionally with ES6 syntax like this.
const normalizeData = ({id, name = ""}) => {
const condition = !!name; // Equivalent to: name !== undefined && name !== "";
return {id, ...(condition && { name })};
}
console.log(normalizeData({id: 123, name: ""}));
console.log(normalizeData({id: 123, name: undefined}));
console.log(normalizeData({id: 123, name: "Phong_Nguyen"}));
Explain:
Using Default function parameters at line code name = "" to avoid undefined of name propety having not included in input object.
Using Destructuring assignment at line code ...(condition && { name })
You can create the object with the id first and then add a name afterwards:
const obj = {id: 123};
if(name) obj.name = name;
axios.post('saveUser', obj);

How to check for undefined when using find on an javascript array

In my array I am using .find to find an object and set its property to some value.
I want to set the name only if there is a value. i.e; check for undefined
Below is my array, am using .find to find the object and set its name.
I want to set only if the object with id === checkid is found.
this.myarray.find(colDef => colDef.id === checkid).name = newname;.
You can do this in one statement with Object.assign like this:
let myArray = [{id: 1, name: 'Boris'}, {id: 2}]
// id 3 does not exist no changes would be made to myArray
Object.assign(myArray.find(x => x.id == 3) || {}, {name: 'Foo'})
// id 1 is there so name would be changed to 'john'
Object.assign(myArray.find(x => x.id == 1) || {}, {name: 'john'})
console.log(myArray)
The idea is to provide Object.assign with an object literal if Array.find does not find an object with the provided id.
The other benefit of this is that you now pass an object for the update so you can easily update more than one property at a time:
let myArray = [{id: 1, name: 'Boris'}, {id: 2}]
// id 1 is there so name would be changed to 'john'
Object.assign(myArray.find(x => x.id == 1) || {}, {name: 'john', state: 'FL'})
console.log(myArray)
You need to run find as it's own statement and check if the result is defined. If so, assign the name, otherwise don't:
let myarray = [
{id: 100},
{id: 10},
{id: 5}
]
let found = myarray.find(colDef => colDef.id === 10)
if (found !== undefined){
found.name = "some name"
}
console.log(found)
// no id 11 found will be undefined
found = myarray.find(colDef => colDef.id === 11)
console.log(found)
As a single line:
this.myarray.find(colDef => colDef.id === checkid).name = newname;
there's no chance to check if find() returned undefined and trying to assign a property to undefined will be an error.
Here is both ways of approaching.
If you dont care, use fireAndForget style.
If you really want to know, a more verbose check.
const arr = [{id:1}];
const fireAndForget = (arr, id, newName) => (arr.find(i => i.id === id)||{}).name = newName;
const checkAndNotify = (arr, id, newName) => {
const p = arr.find(i => i.id === id);
if(!p) return false;
p.name = newName;
return true;
};
console.log(checkAndNotify(arr, 2, 'test'));
console.log(checkAndNotify(arr, 1, 'test'));
console.log(arr);
console.log(fireAndForget(arr, 2, 'test2'));
console.log(fireAndForget(arr, 1, 'test2'));
console.log(arr);
/Check if obj isn't null of undefined, and if it's an object. If if is a valid object, then assign the value for '.name'
const obj = this.myarray.find(colDef => colDef.id === checkid);
if (obj && typeof obj === "object") {
obj.name = newName;
}

Javascript using filter/includes on an array of objects

What is the best way to filter out data that exists within an object?
I was able to do use the below code when data was just an array of values but now I need to filter out any data where the item.QID exists in my array of objects.
Data Obj:
var data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob
}]
Snippet:
// I don't want to include data if this QID is in my object
this.employees = emp.filter(item =>!this.data.includes(item.QID));
From what I understand, includes only works on an array so I need to treat all of the QID values in my object as an array.
Desired Outcome: (assuming item.QID = ABC123)
this.employees = emp.filter(item =>!this.data.includes('ABC123'));
Result:
var data = [{
QID: 'DEF456',
Name: 'Bob'
}]
UPDATE:
Apologies, I left some things a little unclear trying to only include the necessary stuff.
// People Search
this.peopleSearchSub = this.typeahead
.distinctUntilChanged()
.debounceTime(200)
.switchMap(term => this._mapsService.loadEmployees(term))
.subscribe(emp => {
// Exclude all of the current owners
this.employees = emp.filter((item) => item.QID !== this.data.QID);
}, (err) => {
this.employees = [];
});
The above code is what I am working with. data is an object of users I want to exclude from my type-ahead results by filtering them out.
The question is a little ambiguous, but my understanding (correct me if I'm wrong), is that you want to remove all items from a list emp that have the same QID as any item in another list data?
If that's the case, try:
this.employees = emp.filter(item => !this.data.some(d => d.QID === item.QID))
some is an array method that returns true if it's callback is true for any of the arrays elements. So in this case, some(d => d.QID === item.QID) would be true if ANY of the elements of the list data have the same QID as item.
Try Object#hasOwnProperty()
this.employees = emp.filter(item =>item.hasOwnProperty('QID'));
You can use a for ... in to loop through and filter out what you want:
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
let newData = [];
let filterValue = 'ABC123';
for (let value in data) {
if (data[value].QID !== filterValue) {
newData.push(data[value]);
}
}
newData will be your new filtered array in this case
You can use an es6 .filter for that. I also added a couple of elements showing the filtered list and an input to allow changing of the filtered value. This list will update on the click of the button.
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
displayData(data);
function displayData(arr) {
let str = '';
document.getElementById('filterList').innerHTML = '';
arr.forEach((i) => { str += "<li>" + i.QID + ": " + i.Name + "</li>"})
document.getElementById('filterList').innerHTML = str;
}
function filterData() {
let filterValue = document.getElementById('filterInput').value;
filterText (filterValue);
}
function filterText (filterValue) {
let newArr = data.filter((n) => n.QID !== filterValue);
displayData(newArr)
}
<input id="filterInput" type="text" value="ABC123" />
<button type ="button" onclick="filterData()">Filter</button>
<hr/>
<ul id="filterList"><ul>

onChange to check all property of object exist and is not undefined or empty string

This is a very common usage where you have to check whether all fields are filled. I use react onChange and apply e.target.name as key to my object.
like I do console.log(this.state.user); I will get
user : {
name:"something",
age:1
}
but how to check if everything is not empty or null? I check manually like user.name != undefined but my key is more than 10. Is there any better lodash method to do this?
I set state like this
const user = this.state.user;
user[field] = event.target.value;
this.setState({
user
});
You can iterate the values of your object and use reduce method.
const allExist = Object.values(this.state.user)
.reduce(function(accumulator, current){
return accumulator && !!current
}, true);
const user = {
name:"something",
age:1
}
const allExist = Object.keys(user)
.reduce(function(accumulator, current){
return accumulator && !!current
}, true);
console.log(allExist);
You could use Object.keys method - loop the resulting array and check that each key has a valid value:
const user = {
name: "Tom",
age: 28,
address: null,
occupation: "Programmer",
interest: "JavaScript",
dob: undefined
}
const keys = Object.keys(user);
for (let i = 0; i < keys.length; i++) {
if (user[keys[i]] == null) {
console.log(`${keys[i]} needs a value`);
}
}

Return an Object Key and Value from an Array with lodash

I have this Array, I need to get out each name and age value, and then make the name value a new key and the age value a new value.
The Array
var arr = [
{name: "jack", age: 32 },
{name: "jane", age: 34 }
]
My previous code
var monthlyProfit = _.map(arr, function(v) {
var obj = {
v.name: v.age
};
return obj;
});
console.log(monthlyProfit) // Error
Expectation
var arr = [
{jack: 32},
{jane: 34}
]
I am using lodash, but vanilla JS won't be a problem.
The way you're currently trying to define the property will not work. There are multiple ways to achieve what you're trying to achieve, but I'd usually do it like this (using ES5):
var monthlyProfit = _.map(arr, function(v) {
return {[v.name] : v.age};
});
Or like this, as ES6 one-liners:
//using lodash
var monthlyProfit = _.map(arr, ({ name, age }) => ({ [name]: age }))
//or, pure ES6 without lodash:
var monthlyProfit = arr.map(({ name, age }) => ({ [name]: age }))
You should be seeing Syntax Error: Unexpected token . at the line where you're creating the object in your current code.

Categories