How to update an item in an array of an object - javascript

I have a list of people, each with an id. I have to add a tag to a newly created array for a person with a certain id. The json object 'students' already exists and I am updating it using its useState setStudents method but it seems to be returning an unidentified object back. My plan was as follows:
Map through the previousStudents
If the id matches (the person who I'm adding a tag to), then add the tag. The if statement to add a tag is there because the 'tags' property doesn't initially exist, so I make it on the first tag add
If the id doesn't match, just return that student
const updateStudent = (tag, id) => {
setStudents((prevStudents) => {
prevStudents.map((student) => {
if (student.id !== id) return student;
if (student.tags) {
student["tags"].push(tag);
} else {
student["tags"] = [tag];
}
return student;
});
});
};
Sorry if my explanation was confusing but tldr: I'm just trying to add an item to an array of a specified object and it doesn't seem to be working.

A "cleaner" approach would be something like this:
const updateStudent = (tag, id) => {
// form a new students object
let newStudents = students.map(student => {
if(student.id === id) {
student.tags? student.tags.push(tag) : student.tags = [tag];
}
return student;
});
setStudents(newStudents); // set the newly formed object to state
}
It is better to separate the update logic from setting the state

Related

When pushing a new value inside an array it gets totally override - VUEX

Hello so I am creating a filter search and I 'm trying to collect all the key (tags) that the user press, inside an array, however every time that a new value is push it does override the entire array. So I tried a couple of things, like spread syntax, concat, etc. But with no luck.
So my action looks like this:
const setCurrentFilters = async (context, payload) => {
if (payload) {
context.commit('setCurrentFilter');
}
}
My state
state:{
filters: JSON.parse(sessionStorage.getItem('currentFilters') || '[]'),
}
The mutation
setCurrentFilter(state, payload) {
state.filters.push(payload);
sessionStorage.setItem('currentFilters', JSON.stringify(payload));
}
And my getter
currentFilters(state) {
return state.filters;
},
Thank you in advance for any help : )
This is simply because you set const filters = []; which means that the next condition if (filters.length) will always return false (as you just created this array) and therefore the else statement will execute.
in the else statement you basically push the new payload to the empty array you just initialized - which makes your array always hold only the new value
i believe that you just need to remove the const filters = []; line, and access the filters property that exists in your state

How can I delete the proper object property value in JS

I am working through a little practice assignment and have come across this question and for the life of me can't figure it out.
There are tests parameters that I can't see. The object is not a variable I can see, it's just assumed.
Write a function called removePassword that takes in an object.
Delete the property password and return the object.
removePassword=(object)=>{
for(var key in object){
if(object = object[key]){
delete object[key]
}
}return object;
}
I have tried a bunch of different versions of this code, but I don't know how to just delete the property password only without deleting the other property which is a username
Take a look at this solution. You can avoid doing the object copy if you want, it'll work anyway
const removePassword = (user) => {
const userCopy = {...user} // CREATE A COPY OF THE OBJECT
delete userCopy.password // DELETE THE PASSWORD PROPERTY
return userCopy // RETURN UPDATED USER
}
const testUser = {username: 'Mario', password: 'supersecret123'}
console.log(
removePassword(testUser)
)
Could it work for you?
removePassword = (object) => {
delete object.password;
return object;
}
You can see here link
That you can do it simply delete object.password or delete object["password"] :
const removePassword = (object) => {
delete object.password;
return object;
}

How to assign an object from an array to an arrow function?

I am trying to assign a variable with the properties of an object from an array in my redux state. I am trying to loop through the array of objects and assign the variable when the ID of the item matches up to the ID that I am searching for.
I have been trying anything I can from nested if statements, multiple returns, I cannot seem to figure this out.
Currently, this is what I have.
const currItemProps = () => {
this.props.todos.find((todo) => {
(todo.id === this.props.itemID) ?
{ todo } : null
}
);
};
todos is my array I am searching for and the itemID is the ID I am lookking for (both are pieces of redux state).
I am trying to open a modal on the press of a todo that has the properties of the todo. Hence I am trying to assign a variable in my modal file with all of the properties of its current todo (the object from the array).
The find function expects that you'll return True when you find your item.
also, you need to specify a 'return' statement.
const currItemProps = () => {
return this.props.todos.find((todo) => todo.id === this.props.itemID);
};
In case you directly want to return model
const currItemProps = () => {
this.props.todos.find((todo) => {
(todo.id === this.props.itemID) ?
<ComponentName todoProps={todo}/> : null
}
);
};
then you can use the same in render method like {currentProps}

Reactjs filter state by key and value

React Newbie here.
I'm trying to match the value of a specific id located in my state, so I can change some value before updating the database via my api.
The state is
state = {
library: []
}
and then with when the axios changes the state the array looks something like:
0:{_id:"", time:"", value:""},
2:{_id:"", time:"", value:""}
When I run console.log, it reads it like this.
(2) [{…}, {…}]0: {_id: "5c82803ad634ea0bebfb3eff", time: "2019-03-08T14:46:18.663Z", value:""}1: {_id: "5c827fb9d634ea0bebfb3efe", time: "2019-03-08T14:44:09.818Z", value:""}
So basically when I type in a specific input field, identified by it's _id, I need to update the value state of that specific state.
Here's the code I have written so far. _id is the unique key of the input field and event value what I'm typing.
updateRead = (_id, event) => {
console.log(_id);
console.log(event.target.value)
this.setState(?????)
};
Help would be much appreciated!
Cheers
You can use the array map method on the library array in your state, and just return the elements as is if the _id doesn't match, and update the value if the _id does match.
updateRead = (_id, event) => {
const { value } = event.target;
this.setState(prevState => ({
library: prevState.library.map(read => {
if (read._id !== _id) {
return read;
}
return {
...read,
value
};
})
}));
};
Two of the fundamental rules of state in React are:
Never modify state directly
Use the callback version of setState when you're setting state based on existing state (more)
Separately, you can't access properties on the synthetic event after the event handler has returned, so you'll want to grab the value before calling setState (since the call to your callback will be asynchronous).
Within the callback, you copy the array, find the relevant object, copy it, and set the value.
So:
updateRead = (_id, event) => {
const {value} = event.target;
this.setState(({library}) => ({
library: library.map(entry => entry._id === _id ? {...entry, value} : entry)
}));
};
map creates a new array from the previous array's entries. The callback returns a new object if the IDs match (using property spread notation) with an updated value, or the original object (since we don't have to copy objects we aren't modifying).

Angular - Create property in new property of object

Currently, I have a select element in my html which has a ngModel to the object details:
[ngModel]="details?.publicInformation?.firstname"
However, publicInformation may not exist in that object, or if it does, maybe firstname does not exist. No matter the case, in the end, I want to create the following:
[ngModel]="details?.publicInformation?.firstname" (ngModelChange)="details['publicInformation']['firstname'] = $event"
Basically, if the select is triggered, even if neither of publicInformation nor firstname exist, I would like to create them inside details and store the value from the select.
The issue is that I am getting
Cannot set property 'firstname' of undefined
Can someone explain what I am doing wrong here and how can I achieve the result I desire?
You need to initialize details and publicInformation to empty object
public details = {publicInformation : {}};
You should do that when you load the form data.
For example, you might have something like this:
ngOnInit() {
this._someService.loadForm().then((formData: FormData) => {
this.details = formData;
});
}
Then, you could modify that to fill in the missing empty properties you need:
ngOnInit() {
this._someService.loadForm().then((formData: FormData) => {
this.details = formData || {};
if (!this.details.publicInformation) {
this.details.publicInformation = { firstname: '' };
} else if (!this.details.publicInformation.firstname) {
this.details.publicInformation.firstname = '';
}
});
}
However, it would be better to place this logic in the services, so that they are responsible for adding all the necessary empty properties to the data they load, or if you are using Redux, then it should go into the reducers.

Categories