Inserting array item into JS object - javascript

I have a unique situation that I'm struggling with. I have some data like this. Excuse any incorrect terms as I'm fairly new to this.
usersByName: {
"tester": {
0: {
id: 123
name: "Some Name"
data: "Some data"
},
1: {
id: 124
name: "Some Name 2"
data: "Some data 2"
},
2: {
id: 125
name: "Some Name 3"
data: "Some data 4"
},
},
"tester 2": {
0: {
id: 12
name: "Some Name"
data: "Some data"
},
1: {
id: 13
name: "Some Name 2"
data: "Some data 2"
},
}
}
I am returning a piece of data like this.
{
id: 44
name: "Some Name New"
data: "Some data New"
}
and a name like tester 2.
How can I add the new piece of data to the name I have found so the new data gets added as a third element to tester 2.
I am using react and next js so hoping to add it directly to the state if possible.
I think something like this but can't work out the obvious parts of it that are wrong
this.setState((prevState) => ({
usersByName: { // copy all other key-value pairs
newuservar: {
...prevState.usersByName.newuservar, // copy all pizza key-value pairs
X: newData,
},
},
}))

Since I see the user objects have the key start with numbers, I assume they're arrays. Try this:
// newuservar = 'tester 2';
this.setState((prevState) => ({
usersByName: {
...prevState.usersByName,
[newuservar]: prevState.usersByName[newuservar].concat(newData)
},
}))

Related

How do I update selected values in react multiselect

I have a modal in which I edit my model. In my form, I also have a multi-select tag field. The "tags" is an array of objects with labels and values as show below.
There is a dummy tags object (mimicking a database) which all the tags are selected from.
const dummyTags = [
{ label: "Test 1", value: "Test 1" },
{ label: "Test 2", value: "Test 2" },
{ label: "Test 3", value: "Test 3" },
];
So, if I selected "Test 1" and "Test 2", my tags array becomes (only the values are then saved in the database):
const tgs = [
{
label: "Test 1",
value: "Test 1"
},
{
label: "Test 2",
value: "Test 2"
}
];
However, during update, the tags come from the database as ['Test 1','Test 2'].
I want to use the tags from the database shown in the line above to compare the dummyTags array so I can have a new array of objects with values like the tgs array above.
At the moment, this is what I am doing:
let newtags = [];
if (groupTags.length > 0) { //groupTags is the tags from the database
groupTags?.forEach((tag) => {
newtags.push({ label: tag, value: tag });
});
}
This works, but I think it's not reliable. What if the label and value are not the same for a particular tag?
Is there a better way of implementing this?
const arr = ['Test 1','Test 2', 'Test 3']
const result = arr.map(d => ({label: d, value: d}));
console.log(result)

Returning the ids from the object within the arrays

I have a multidimensional javascript array of objects that I am trying to use to simply collate the Unit id into a new array as shown below.
What is the best solution for returning the id within the inner value so I just get an array of the ids whatever I try seems to not work
[
{
units: [
{
id: 10000282,
name: "Group 1",
},
{
id: 10000340,
name: "Group 2",
},
{
id: 10000341,
name: "Group 3",
},
],
},
{
units: [
{
id: 10000334,
name: "Group 4",
},
],
},
]
Expected output - just return an array with simply the ids
e.g
ids = [ 10000282, 10000340, 10000341, 10000334 ]
Assuming that data is in variable data:
> data.map(o => o.units.map(u => u.id)).flat()
[ 10000282, 10000340, 10000341, 10000334 ]
This assumes you're in an environment where .flat() is a thing.
If that's not the case, the longer way around is
const ids = [];
data.forEach(o => {
o.units.forEach(u => {
ids.push(u.id);
});
});

How can this array manipulation problem be solved scalably?

I am working with JS and came across an interesting Array manipulation problem. I'm aware that the problem can be solved with a tremendous if - else if clause, but am actually looking for a more scalable answer.
I have two arrays (let's call them input and output) whose contents are related to each other. The first array contains a list of ids, and the second array is actually a response from an API (I have no power over the API) matching the ids of the input array.
Examples: If I have an input array of [1, 2, 3] I will end up with an output array of
[
{ id: 1, data: "Some data for id 1" },
{ id: 2, data: "Some data for id 2" },
{ id: 3, data: "Some data for id 3" }
]
So far so good. However, the problem arises if I have an input array like [1, 2, 2], which is possible and intentional. In this situation I end with an output array of
[
{ id: 1, data: "Some data for id 1" },
{ id: 2, data: "Some data for id 2" }
]
In the above case I would need to have the output array be of length === 3 and the third item to be a copy of the second item like so
[
{ id: 1, data: "Some data for id 1" },
{ id: 2, data: "Some data for id 2" },
{ id: 2, data: "Some data for id 2" }
]
Two more examples for clarity:
Input: [4, 4, 4], what I get:
[
{ id: 4, data: "Some data for id 4" }
]
What I need to achieve:
[
{ id: 4, data: "Some data for id 4" },
{ id: 4, data: "Some data for id 4" },
{ id: 4, data: "Some data for id 4" }
]
Last one, input: [3, 3, 7]
What I get:
[
{ id: 3, data: "Some data for id 3" },
{ id: 7, data: "Some data for id 7" }
]
What I need to achieve:
[
{ id: 3, data: "Some data for id 3" },
{ id: 3, data: "Some data for id 3" },
{ id: 7, data: "Some data for id 7" },
]
I am working with a maximum array length of three, so an if-else clause comparing lengths and values is sufficient for this, but is there a dynamic and scalable way to manipulate the output array in the intended way? I was not able to think if anything from my mind.
EDIT: I should add that the data part can be anything, not just the text I am giving here.
Thanks in advance!
The map function allows us to create new arrays from a pre-existing one.
const outputArray = inputArray.map(id => {
return {
id: id,
data: "Some data for id " + id
}
});

convert array values to object, add keys based on index position

I'm using a data source in a handlebars template. When I fetch the data the resulting object contains nested arrays like:
["10004", "Some title", "Some Description", "$19.95", "Some other text here..."]
I want to convert the array values to objects and set/access the object keys (this is for inclusion on handlebars template). any advice helpful. ty!
for more info: this is what I have constructed so far.
// data from API http response is var data
let dataObj = {};
dataObj =
_.chain(data)
.values()
.map(function(el){
return {'product': el};
});
my result is like so:
{"products": [
{
"product":[
"123456",
"Some title",
"Some descritpion.Lorem ipsum"
]
}
]};
but what I'm looking for is:
{
"products":[
{
"product":[
{
"id":"123456"
},
{
"title":"Some title"
},
{
"description":"Some descritpion.Lorem ipsum"
},
{
"price":"$103.05"
}
]
}
]
}
edit: thanks again for dropping by!
In this case, you can create a simple convert function and reuse it.
function convert(data){
return {
product: [{
id: data[0],
title: data[1],
description: data[2],
price: data[3]
}]
}
}
let data = ["10004", "Some title", "Some Description", "$19.95", "Some other text here..."];
function convert(data){
return {
product: [{
id: data[0],
title: data[1],
description: data[2],
price: data[3]
}]
}
}
console.log(convert(data))

JavaScript | Spread operator update nested value

I am trying to update a nested value of an object using the spread operator. This is my first time using this and I believe I am pretty close to achieving my end goal but I just can't seem to figure out what I actually need to do next.
I have an array which is structured like this:
[
{
name: "Category 1",
posts: [
{
id: 1,
published: false,
category: "Category 1"
},
{
id: 2,
published: true,
category: "Category 1"
}
]
},
{
name: "Category 2",
posts: [
{
id: 3,
published: true,
category: "Category 2"
},
{
id: 4,
published: true,
category: "Category 2"
}
]
}
]
On the click of a button I am trying to update the published value, and as I am using React I need to set the state. So it got recommended to me that I update using the spread operator.
onPostClick(post) {
post.pubished = !post.published;
this.setState({...this.state.posts[post.category], post})
}
If I log out the result of {...this.state.posts[post.category], post} I can see that the published is getting added to the parent which forms:
{
name: "Category 1",
published: false,
posts: [
...
]
}
Obviously this isn't the intended result, I want it to update the actual object within the posts object.
I have tried to do something like this.setState({...this.state.posts[post.category].posts, post}) but I get a message that it is undefined.
You can't access your data with this.state.posts[post.category]. posts data in the objects of the array.
You can make a filter to find your category object in array and change its posts value.
onPostClick(post) {
//CLONE YOUR DATA
var postArray = this.state.posts;
//FIND YOUR CATEGORY OBJECT IN ARRAY
var categoryIndex = postArray.findIndex(function(obj){
return obj.name === post.category;
});
//FIND YOUR POST AND CHANGE PUBLISHED VALUE
postArray[categoryIndex].posts.forEach(function(item){
if (item.id === post.id) {
item.published = !item.published;
}
});
//SET TO STATE TO RERENDER
this.setState({ posts: postArray});
}
This should work if your name of the state is true.
just adding, we know there are many ways to succeed, maybe you also want to try this way too..
onPostClick = post => {
let published = this.state.data.map((item, i) => {
item.posts.map((item_post, i) => {
if (item_post.category === post.category) {
item_post.published = !post.published;
}
});
});
this.setState({ ...this.state.data, published });
};

Categories

Resources