Home > Software design >  How to insert object that hasn't been defined in a loop that does define it
How to insert object that hasn't been defined in a loop that does define it

Time:08-18

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);

  • Related