I have the next object. This is used to make calls to an API and get data.
const extractorData = [
{
name: 'newshub',
link: 'https://direct.faforever.com/wp-json/wp/v2/posts/?per_page=100&_embed&_fields=_links.author,_links.wp:featuredmedia,_embedded,title,content.rendered,date,categories&categories=587',
sortingCriteria: {
date: item.date,
title: item.title.rendered,
content: item.content.rendered,
author: item._embedded.author[0].name,
media: item._embedded['wp:featuredmedia'][0].source_url,
},
},
];
in my code, the 'item' variable hasn't been defined yet. It is defined in this loop.
let data = dataObjectToArray.map(item => ({
date: item.date,
title: item.title.rendered,
content: item.content.rendered,
author: item._embedded.author[0].name,
media: item._embedded['wp:featuredmedia'][0].source_url,
}));
'item' simply is the naming convention for each item inside 'dataObjectToArray'. However, I re-use this piece of code a lot (while changing the sorting parameters such as date, title, etc). Therefore, I want to put these parameters into an object and just cycle through the objects with the parameters rather than repeating the same line of code multiple times.
The issue is since 'item' isn't defined, JS throws an error about how item isn't defined on extractorData. I've tried putting the 'item.date' into a string but then it stays a string. What could be a solution to being able to insert this object into the loop/.map correctly? Thanks!
Here is what the code should look like, but it doesnt work because item isn't defined in extractorData.
let data = dataObjectToArray.map((item, index) => (
extractorData[index].sortingCriteria
));
EDIT:
This produces the next error:
ReferenceError: item is not defined
It references to this line of code, because item isn't defined in the code.
sortingCriteria: {
date: item.date, <=== ERROR
title: item.title.rendered,
content: item.content.rendered,
author: item._embedded.author[0].name,
media: item._embedded['wp:featuredmedia'][0].source_url,
},
CodePudding user response:
If I understood correctly, you want to configure via the sortingCriteria
object which nested values from an item
object should be collected into a new object, which follows the sortingCriteria
template.
You cannot reference item
in sortingCriteria
, but you can list the path of keys to follow in it:
const extractorData = {
name: 'newshub',
link: 'https://direct.faforever.com/wp-json/wp/v2/posts/?per_page=100&_embed&_fields=_links.author,_links.wp:featuredmedia,_embedded,title,content.rendered,date,categories&categories=587',
sortingCriteria: {
date: ["date"],
title: ["title", "rendered"],
content: ["content", "rendered"],
author: ["_embedded", "author", 0, "name"],
media: ["_embedded", "wp:featuredmedia", 0, "source_url"],
},
};
Then the callback to your map
function should follow those paths in their item
object to retrieve the corresponding value. The functions Object.entries
and Object.fromEntries
can serve in that process:
const data = dataObjectToArray.map(item => Object.fromEntries(
Object.entries(extractorData.sortingCriteria).map(([k, path]) =>
[k, path.reduce((acc, key) => acc?.[key], item)]
)
));
Here is a demo using an array with one data object:
const extractorData = {
name: 'newshub',
link: 'https://direct.faforever.com/wp-json/wp/v2/posts/?per_page=100&_embed&_fields=_links.author,_links.wp:featuredmedia,_embedded,title,content.rendered,date,categories&categories=587',
sortingCriteria: {
date: ["date"],
title: ["title", "rendered"],
content: ["content", "rendered"],
author: ["_embedded", "author", 0, "name"],
media: ["_embedded", "wp:featuredmedia", 0, "source_url"],
},
};
// Sample data
const dataObjectToArray = [{
date: "2000-02-01",
title: { rendered: "mytitle" },
content: { rendered: "mycontent" },
_embedded: {
author: [{ name: "Jen" }],
["wp:featuredmedia"]: [{ source_url: "http" }]
}
}];
const data = dataObjectToArray.map(item => Object.fromEntries(
Object.entries(extractorData.sortingCriteria).map(([k, path]) =>
[k, path.reduce((acc, key) => acc[key], item)]
)
));
console.log(data);