Transforming deeply nested (dynamic) data w/ async function

55 Views Asked by At

I have an object that looks like this:

{
  name: 'Appropriate Trip Name',
  mood: 'Provided trip mood',
  itinerary: [
    {
      destination: 'Destination 1',
      num_days: 2,
      recommendations: {
        day_1: [
          {
            name: 'Day 1, Suggestion 1',
            justification: 'Justification 1',
            official_name: 'Official Name 1',
          },
          {
            name: 'Day 1, Suggestion 2',
            justification: 'Justification 2',
            official_name: 'Official Name 2',
          },
        ],
        day_2: [
          {
            name: 'Day 2, Suggestion 1',
            justification: 'Justification 1',
            official_name: 'Official Name 1',
          },
          {
            name: 'Day 2, Suggestion 2',
            justification: 'Justification 2',
            official_name: 'Official Name 2',
          },
        ],
      },
    },
    {
      destination: 'Destination 2',
      num_days: 1,
      recommendations: {
        day_1: [
          {
            name: 'Day 1, Suggestion 1',
            justification: 'Justification 1',
            official_name: 'Official Name 1',
          },
        ],
      },
    },
  ],
}

This is just an example--a real object can have x destination objects within the itinerary array, y days within each recommendations array, and z recommendations within each day array.

I need to access each recommendation object...

{
  name: 'Day 1, Suggestion 1',
  justification: 'Justification 1',
  official_name: 'Official Name 1',
}

...and enrich it with additional properties. I have a function that accepts a recommendation object and returns the enriched object, but the process is async, as it fetches data for these new properties from several API endpoints.

I can do a few loops within loops and get at each of the recommendation objects, but no matter what possible combinations of async/await, Promise.all(), Promise.resolve() I try, the resulting itinerary array ends up with nested unresolved promises.

In general, I am hoping you might have some good suggestions about the best ways to go about achieving the transformation of this object that I have described above. Thanks!

1

There are 1 best solutions below

2
dblinkhorn On

In trying to post the closest I had gotten to my goal previously, and in response to the comments to the original question about sharing what I've tried, I came up with this (which works!):

for (let destination of itinerary) {
  for (let day in destination.recommendations) {
    for (let recommendation of destination.recommendations[day]) {
      itinerary[itinerary.indexOf(destination)].recommendations[day][destination.recommendations[day].indexOf(recommendation)] = await enrichRecommendation(recommendation);
    }
  }
}

The original itinerary is successfully enriched in the intended manner, but this is just horribly unreadable and a mess. I was trying to do this with a combination of .forEach() & .map(), but I was screwing up the data structure. I would appreciate any advice on how to accomplish this in a more elegant way!