How do I populate an array of objects where every object has an array inside of it using response from rest API? - javascript

I can't google the right solution for this for about an hour straight,
So I'm getting a response from the API that looks like this:
[
{
"Name": "name1",
"Title": "Name One",
"Children": [
{
"Name": "Name 1.1",
"Title": "Name one point one"
},
]
And I need it to fit this kind of "mold" for the data to fit in:
{
title: 'Name One',
value: 'name1',
key: '1',
children: [
{
title: 'Name one point one',
value: 'Name 1.1',
key: 'key1',
},
I am trying to achieve this using a foreach but It's not working as intended because I need to do this all in one instance of a foreach.
Here's what I gave a go to(vue2):
created() {
getData().then(response => {
const formattedResponse = []
response.forEach((el, key) => {
formattedResponse.title = response.Title
formattedResponse.name = response.Name
formattedResponse.children = response.Children
})
})

Use map over the main array and use destructuring assignment to extract the properties by key, and relabel them, and then do exactly the same with the children array. Then return the updated array of objects.
const data=[{Name:"name1",Title:"Name One",Children:[{Name:"Name 1.1",Title:"Name one point one"}]},{Name:"name2",Title:"Name Two",Children:[{Name:"Name 1.2",Title:"Name one point two"}]}];
const result = data.map((obj, key) => {
const { Title: title, Name: value } = obj;
const children = obj.Children.map(obj => {
const { Title: title, Name: value } = obj;
return { title, value, key: (key + 1).toString() };
});
return { title, value, children };
});
console.log(result);

Your API response is JSON. All you need to do is:
var resp=JSON.parse(API response);

Related

How can I extract and pair the values of an array based object

I'm trying to create a String based upon an object consisting of several key-value pairs.
Example:
[{ name: 'cookie1', value: 'false' },
{ name: 'cookie2', value: '123' },
{ name: 'cookie3',value: 'abc'}]
What I'm trying to achieve (string):
cookie1: false, cookie2: 123, cookie3: abc
I've tried to extract just the val using map like this (played around moving around values):
var output = cookies.map(d => {
return {
"name": d.name,
"value": d.value,
}
})
One way to do this is to map the array of objects into name: value strings and then join them with , :
const data = [{ name: 'cookie1', value: 'false' },
{ name: 'cookie2', value: '123' },
{ name: 'cookie3',value: 'abc'}]
const result = data.map(({ name, value }) => `${name}: ${value}`).join(', ')
console.log(result)

Javascript - Update object in array by id and move it to the first index

I have this array:
const chats = [
{ id: "chat-1", msg: { text: "World", date: (a date) } },
{ id: "chat-2", msg: { text: "Hello", date: (a date) } },
];
After receiving updates from my database, I receive this object:
// The second chat with update data
{ id: "chat-2", msg: { text: "Bye", date: (a date) } },
How can I (using ES6) replace the chat object from the original chats array and move it to the first index?
For now, I am doing this, but I am looking for a fastest way (smaller O)
// Get the modified chat
const modifiedChat = response.data;
// Search the modified chat in the chats array by id
const chatIndex = chats.findIndex(
(chat) => chat.id === modifiedChat.id
);
// Finally, using spread syntax, add the updated chat to the head of our current chats array
chats = [
modifiedChat,
...chats.slice(0, chatIndex),
...chats.slice(chatIndex + 1),
];
You can do the following,
const chats = [
{ id: "chat-1", msg: { text: "World", date: '' } },
{ id: "chat-2", msg: { text: "Hello", date: '' } },
];
const modifiedChat = { id: "chat-2", msg: { text: "Bye", date: '' } };
const newChats = [modifiedChat, ...chats.filter(item => item.id !== modifiedChat.id)];
console.log(newChats);
You can do something similar to how LRU cache works. You can now access every chat in O(1)

How to filter an object array based on the contents of child array?

I have this data
var data = [
{
title: "App development summary",
category: [],
},
{
title: "to experiment 2",
category: [],
},
{
title: "Some of these books I have read",
category: [
{
_id: "5f7c99faab20d14196f2062e",
name: "books",
},
{
_id: "5f7c99faab20d14196f2062f",
name: "to read",
},
],
},
{
title: "Quora users and snippets",
category: [
{
_id: "5f7c99feab20d14196f20631",
name: "quora",
},
],
},
{
title: "Politics to research",
category: [
{
_id: "5f7c9a02ab20d14196f20633",
name: "politics",
},
],
},
];
Say I want to get all the entries with the category of books. I tried doing this:
var bookCat = data.map(note => {
return note.category.map(cat => {
if(cat.name === "books" ) return note
})
})
But the result comes back with some empty and undefined arrays.
I was able to filter the empty arrays (at one point) but not the undefined
Edit
In plain English "if the object ha category.name "books", give me the title"
Filter by whether the array's category contains at least one name which is books:
var data=[{title:"App development summary",category:[]},{title:"to experiment 2",category:[]},{title:"Some of these books I have read",category:[{_id:"5f7c99faab20d14196f2062e",name:"books"},{_id:"5f7c99faab20d14196f2062f",name:"to read"}]},{title:"Quora users and snippets",category:[{_id:"5f7c99feab20d14196f20631",name:"quora"}]},{title:"Politics to research",category:[{_id:"5f7c9a02ab20d14196f20633",name:"politics"}]}];
const output = data
.filter(item => item.category.some(
({ name }) => name === 'books'
));
console.log(output);
If there's guaranteed to be only a single matching object, use .find instead:
var data=[{title:"App development summary",category:[]},{title:"to experiment 2",category:[]},{title:"Some of these books I have read",category:[{_id:"5f7c99faab20d14196f2062e",name:"books"},{_id:"5f7c99faab20d14196f2062f",name:"to read"}]},{title:"Quora users and snippets",category:[{_id:"5f7c99feab20d14196f20631",name:"quora"}]},{title:"Politics to research",category:[{_id:"5f7c9a02ab20d14196f20633",name:"politics"}]}];
const output = data
.find(item => item.category.some(
({ name }) => name === 'books'
));
console.log(output);

Loop through and delete elements in an array of objects

In my Vue.js project I have an array of objects which I want to list through and display in the browser.
My array contains four objects, I want to display only 3. The way I choose the 3 objects are dependent on a preference setting that the user has chosen somewhere else in the project and stored in a variable (below it is called userPreference). I am currently stuck on the best and most efficient way to remove one of the objects from my array based on the userPreference value.
My v-for in my template
<ul v-for="item in getOutroItems"><li>item<li></ul>
My object:
data() {
return {
outroItems: [{ title: "outro1", text: "XYZ" }, { title: "outro2", text: "ABC" }, { title: "outro3",
text`enter code here`: "QRS" }, { title: "outro4", text: "TUV" }],
userPreference: ""
};
}
My computed property (this is what I have so far)
getOutroItems() {
this.outroItems.filter((value) => {
if(this.userPreference === "newsletter") {
/// here I want to remove outro2 from my array and return an array with the other 3 values
} else (this.userPreference === "noNewsletter") {
/// here I want to remove outro3 from my array and return an array with the other 3 values
}
})
}
So, what is the best way to remove a specific element from an array?
Thanks in advance, and let me know if anything wasn't clear enough.
Your requirement can be fulfilled by below code as array.filter just wants true or false in its return to accept or remove an element from its array.
getOutroItems() {
this.outroItems.filter((value) => {
if(this.userPreference === "newsletter") {
// here I want to remove outro2 from my array and return an array with the other 3 values
return value.title != 'outro2';
} else (this.userPreference === "noNewsletter") {
// here I want to remove outro3 from my array and return an array with the other 3 values
return value.title != 'outro3';
}
})
}
However if you want to not create another array if it is big. you should go with swapping such elements to be removed with the end indexed element in the array and popping those many elements from the array.
There are multiple ways of getting the correct items from an array.
My preferred method and in your example: Using array.filter
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
const leftOverItems = outroItems.filter((item) => item.title !== "outro2");
console.log(leftOverItems);
Another option is to find the index of the item to remove and then remove it with splice
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
const itemToDelete = outroItems.find((item) => item.title === "outro2");
const indexToDelete = outroItems.indexOf(itemToDelete);
outroItems.splice(indexToDelete, 1);
console.log(outroItems);
Combining any of the functions above with a function will prevent you from writing duplicate code.
const itemToRemove = (arr, attr, name) => {
return arr.filter((item) => item[attr] !== name);
}
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
// Remove from "outroItems" where "title" is "outro2"
const removed2 = itemToRemove(outroItems, "title", "outro2");
// Remove from "outroItems" where "title" is "outro3"
const removed3 = itemToRemove(outroItems, "title", "outro3");
// Remove from "outroItems" where "text" is "TUV"
const removedTUV = itemToRemove(outroItems, "text", "TUV");
console.log(removed2);
console.log(removed3);
console.log(removedTUV);

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