Find by key and replace the value in an object - javascript

I'm a bit new with javascript. Is there a way to find all icon and get their value and then replace their values with a new one?
I need to replace all of fa/FaCopy with fcb/FcbCopy in the json payload below. Any libraries or functions you can share?
[
{
"section": "feature-list",
"data": {
"title": "Title here",
"body": "body here",
"features": [
{
"title": "Title here 1",
"image": "body here",
"icon": "fa/FaCopy"
},
{
"title": "Title here 2",
"image": "body here",
"icon": "fa/FaCopy"
},
{
"title": "Title here 3",
"image": "body here",
"icon": "fa/FaCopy"
}
]
}
},
{
"section": "title-list",
"data": {
"title": "Title here",
"titles": {
"list": [
{
"title": "Title here 1",
"icon": "fa/FaCopy"
},
{
"title": "Title here 2",
"icon": "fa/FaCopy"
},
{
"title": "Title here 3",
"icon": "fa/FaCopy"
}
]
}
}
}
]

This will be very customized solution and deeply depended on your data.
If your data type will not change and remain same then you could use/modify something like this.
// DATA = Your array
const result = DATA.map((list) => ({
...list,
data: {
...list.data,
features: list.data.features?.map((feature) => ({
...feature,
icon: feature.icon === 'fa/FaCopy' ? 'fcb/FcbCopy' : feature.icon
})),
},
}));
console.log(result); // your expected result

Related

Group by property of an object within a nested array

How would you group an array by a property of the objects in a nested array. Either vanilla or lodash.
For example, how would you group an array of tasks by the assignee, when tasks can have more than one person assigned.
Example data:
[
{
"assignees": [
{
"name": "John",
"uid": "id0001"
},
{
"name": "Sally",
"uid": "id0002"
}
],
"title": "Task 1",
"status": "To do"
},
{
"assignees": [
{
"name": "John",
"uid": "id0001"
}
],
"title": "Task 2",
"status": "To do"
},
{
"assignees": [
{
"name": "Sally",
"uid": "id0002"
}
],
"title": "Task 3",
"status": "To do"
}
]
Example desired result:
{
"id0001": {
"name": "John",
"tasks": [
{
"title": "Task 1",
"status": "To do"
},
{
"title": "Task 2",
"status": "To do"
}
]
}
},
{
"id0002": {
"name": "Sally",
"tasks": [
{
"title": "Task 1",
"status": "To do"
},
{
"title": "Task 3",
"status": "To do"
}
]
}
}
I have a lot of things both vanilla and lodash - a simple example is below. I was expecting an array of three groups. One for Sally, one for John and one for Sally and John:
const grouped = _.groupBy(taskList, (task) => task.assignees);
But that returns one group [object Object] with all the tasks in it.
Since uids are unique, the Array seems like an overhead.
I suggest to get an Object literal with the tasks grouped by the user's uids: like:
{
id0001: {...user, tasks: []},
id0002: {...user, tasks: []},
}
Example:
const groupTasksByUserId = (arr) => arr.reduce((ob, {assignees, ...task}) => {
assignees?.forEach((user) => {
ob[user.uid] ??= {...user, tasks: []};
ob[user.uid].tasks.push(task)
});
return ob;
}, {});
const data = [{
"assignees": [{"name": "John", "uid": "id0001"}, {"name": "Sally","uid": "id0002"}],
"title": "Task 1",
"status": "To do"
}, {
"assignees": [{"name": "John", "uid": "id0001"}],
"title": "Task 2",
"status": "To do"
}, {
"assignees": [{"name": "Sally", "uid": "id0002"}],
"title": "Task 3",
"status": "To do"
}];
const res = groupTasksByUserId(data);
// console.log(res);
console.log(JSON.stringify(res, 0, 2));
Find out more about the above used Array methods (reduce and forEach) on MDN Docs

Remove item from nested array object in Javascript by key value

I have object like this:
{
"id": 1,
"name": "first",
"sections": [
{
"id": 1,
"title": "First section",
"contents": [
{
"id": "123",
"title": "Sample title 1",
"description": "<html>code</html>",
},
{
"id": "124",
"title": "Sample title 2",
"description": "<html>code</html>"
},
{
"id": "125",
"title": "Some other sample",
"description": "<html>code</html>"
}
]
},
{
"id": 2,
"title": "Second section",
"contents": [
{
"id": "126",
"title": "Sample title 126",
"description": "<html>code</html>"
},
{
"id": "127",
"title": "Sample title 127",
"description": "<html>code</html>"
}
]
}
]
}
I want to remove specific object from contents array by its id (all those ids are unique).
I can easily find element I want to remove, but I'm unable to find in which section this element is to splice it later.
obj.sections.forEach(function(section) {
section.contents.forEach((content) => {
if (content.id == 125) {
console.log(content)
console.log(section)
}
})
})
In above code console.log(sections) returns undefined. How can I get position in sections array which contains contents array that has specific id. For example, id: 125 would return sections position 0, so I can use splice to remove that element.
If my approach is completely wrong please point me in right direction, thanks :)
You could use .filter() instead of .splice(). .filter() will keep all items which you return true for and discard of those which you return false for. So, if the current section's content's object has an id equal to the one you want to remove you can return false to remove it, otherwise return true to keep that item. You can use this with .map() to map each section object to a new one with an updated contents array:
const obj = { "id": 1, "name": "first", "sections": [ { "id": 1, "title": "First section", "contents": [ { "id": "123", "title": "Sample title 1", "description": "<html>code</html>", }, { "id": "124", "title": "Sample title 2", "description": "<html>code</html>" }, { "id": "125", "title": "Some other sample", "description": "<html>code</html>" } ] }, { "id": 2, "title": "Second section", "contents": [ { "id": "126", "title": "Sample title 126", "description": "<html>code</html>" }, { "id": "127", "title": "Sample title 127", "description": "<html>code</html>" } ] } ] };
const idToRemove = 125;
obj.sections = obj.sections.map(
sec => ({...sec, contents: sec.contents.filter(({id}) => id != idToRemove)})
);
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore */
Why not use a simple filter for accomplishing the task. Also, it will be much cleaner and immutable way of doing it.
let newArrWithoutContentWithGivenId = obj.sections.map(section =>
({...section, contents: section.contents.filter(content =>
content.id != 125)}));
Here, we are mapping each section whose content does not contain the ID 125. In short, section > content.id != 125 will be removed from the new array.
Hope it helps :)
Note: Code is not tested, it is just to help you find a way to do it cleanly.
You only need to use the second argument of forEach :)
obj.sections.forEach(function(section, sectionIndex) {
section.contents.forEach((content, contentIndex) => {
if (content.id == 125) {
// use the sectionIndex and contentIndex to remove
}
})
})

Using Map() function to pull out double nested JSON data with ReactJS

I'm trying to pull out the individual images in the "images" object below under "details" section.
Seem to just be getting nothing printing out. Looking for the correct way to pull within the details.images.image1,2, or 3.
Here is the JSON data I'm working with so far:
{
"books": [
{
"title": "title 1",
"image": "/image1.jpg"
},
{
"title": "title 2",
"image": "/image2.jpg"
}
],
"details": [
{
"author": "book author",
"name": "Book name",
"price": 34.99,
"publisher": "Penguin Books",
"images": [
{
"image1": "/image1.jpg",
"image2": "/image2.jpg",
"image3": "/image3.jpg"
}
]
}
]
}
Also here is the JSON call I'm making in a Book component:
{staticdata.details.map(detail => (
<Book
book_name={detail.author}
book_price={detail.price}
image={detail.images.image1}
/>
))}
Here's an example of accessing those nested properties and logging them to the console. It appears your attempt was mostly correct, but images is an array.
const data = {
"books": [
{
"title": "title 1",
"image": "/image1.jpg"
},
{
"title": "title 2",
"image": "/image2.jpg"
}
],
"details": [
{
"author": "book author",
"name": "Book name",
"price": 34.99,
"publisher": "Penguin Books",
"images": [
{
"image1": "/image1.jpg",
"image2": "/image2.jpg",
"image3": "/image3.jpg"
}
]
}
]
}
data.details.map(detail => {
console.log(detail.author, detail.price, detail.images[0].image1);
});

Looping through complex and nested JSON using this example json

I'm trying to loop a complex/nested JSON object. I'm trying to loop var_color.color.primary.
Questions:
What causes this error?
Cannot read property '_id' of undefined
How can I output the primary?
Kindly use only vanilla Javascript.
Example Data
products.json file
{
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
}
// main.js
async function getData(product) {
let response = await fetch(`./api/products/${product}`);
let data = await response.json();
return data;
}
getData('products.json').then(data => {
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
for (let j in all) {
let variantColor = all.var_color[j].primary;
console.log(variantColor);
}
}
});
This is my current script as of the moment.
all.var_color does not exist in each entry, therefore you need to check for its presence.
You are treating all.var_color[j] as if it were an array, but it is an object.
To get the primary color, replace the inner loop (for (let j in all)) with a simple test:
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
var data = {
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
};
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
}

Constructing multidimensional array out of other arrays

I’m using an external service to pull the events of an organisation (GetEvents). Example of what is returned:
{
"Result":"success",
"Key":"12345",
"Data":[
{"ID":"GFDCV34","lastChangedDate":"2015-12-03 11:14:27"},
{"ID":"IDJHE23","lastChangedDate":"2015-12-03 15:17:47"},
{"ID":"KDJBD34","lastChangedDate":"2015-12-03 05:25:11"}
]
}
Next, I can pull details of a certain event (GetEventDetails). The ID of the event is required as data parameter. I made a function getdetails(id); that returns the details.
For example, for getdetails('KDJBD34'), it gives me:
{
"Result":"success",
"Key":"52523",
"Data":[
{
"ID": "KDJBD34",
"name": "Name of event 3",
"date": "date of event 3",
"location": "location of event 3",
"lastChangedDate":"2015-12-03 05:25:11"
}
]
}
I want to construct an array containing all the events and their details, like this:
{
"Result": "success",
"Key": "12345",
"Data":[
{
"ID": "GFDCV34",
"name": "Name of event 1",
"date": "date of event 1",
"location": "location of event 1",
"lastChangedDate": "2015-12-03 11:14:27"
},
{
"ID": "IDJHE23",
"name": "Name of event 2",
"date": "date of event 2",
"location": "location of event 2",
"lastChangedDate": "2015-12-03 15:17:47"
},
{
"ID": "KDJBD34",
"name": "Name of event 3",
"date": "date of event 3",
"location": "location of event 3",
"lastChangedDate":"2015-12-03 05:25:11"
}
]
}
Anyone who can point me in the right direction?
You should operate through your first results and attach the new retrieved properties
var res = {
"Result": "success",
"Key": "12345",
"Data": [{
"ID": "GFDCV34",
"lastChangedDate": "2015-12-03 11:14:27"
}, {
"ID": "IDJHE23",
"lastChangedDate": "2015-12-03 15:17:47"
}, {
"ID": "KDJBD34",
"lastChangedDate": "2015-12-03 05:25:11"
}]
};
var tmp;
res.Data.map(function(val,i){
tmp = getdetails(val.ID);
Object.keys(tmp.Data[0]).map(function(v,j){
val[v] = tmp.Data[0][v];
});
});
Demo

Categories