Search code examples
javascriptnode.jsflatten

Node 'Flatten/Merge' Array of Objects Containing Arrays and Display with forEach in EJS


Apologies for any repeats here, please point me in the direction of a solution if one exists.

Any other time, I seem able to display array data in ejs no problem, but this new flatten function has me stumped.

I have a nested array:

var array = 
[{
  page: {
    results: [{
        id: "1234",
        type: "page",
        title: "Deprecated Spec",
        children: {
          page: {
            results: [{
                id: "5678",
                type: "page",
                title: "Deprecated | Cash Spec"
              },
              {
                id: "9101",
                type: "page",
                title: "Deprecated | Ledger Spec",
              }
            ],
          },
        },
      },
      {
        id: "1121",
        type: "page",
        title: "Work Spec"
      }
    ]
  }
}];

And I have a flatten function:

function flatten(arr) {
  let flattened = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      flattened = flattened.concat(flatten(arr[i]));
    } else {
      flattened.push(arr[i]);
    }
  }
  return flattened;
}

I set a const and console.log:

const newArr = (flatten(array))

console.log(newArr);

In the terminal I receive: [ { page: { results: [Array] } } ]

For what it's worth, I've also tried flattening this nested array with these methods, and both return the same results.

const newArr2 = Array.prototype.concat.apply([], array);

const newArr3 = array.flat();

Hmm ok, I figure I can forEach and display the data on the .ejs page, which is set as:

<% newArr.forEach(function (newArr){ %> 
        <%= newArr.title %>
    <% }) %> 

But this shows nothing.

I have the res.render functioning properly as I am able to send and display other arrays/data sets.

If I try to "get into the array" with something like this: newArr[0].page.results, or any other variances, they don't work.

What am I missing to see my flattened array (using the recursive function) in both the console.log and on my ejs page?

UPDATED: Per comments below, here is my desired output for the arrays and objects seen in var array:

[{
  page: {
    results: [
       {
        id: "1234",
        type: "page",
        title: "Deprecated Spec"
       },
       {
        id: "5678",
        type: "page",
        title: "Deprecated | Cash Spec"
       },
       {
        id: "9101",
        type: "page",
        title: "Deprecated | Ledger Spec"
        },
        {
        id: "1121",
        type: "page",
        title: "Work Spec"
        }
    ]
  }
}];

Here is a pic of my current console.log can see array/objects and console log

Many Thanks!


Solution

  • You should adapt your code to flatten the array like this to achieve the desired output:

    const array = [
      {
        page: {
          results: [
            {
              id: '1234',
              type: 'page',
              title: 'Deprecated Spec',
              children: {
                page: {
                  results: [
                    {
                      id: '5678',
                      type: 'page',
                      title: 'Deprecated | Cash Spec',
                    },
                    {
                      id: '9101',
                      type: 'page',
                      title: 'Deprecated | Ledger Spec',
                    },
                  ],
                },
              },
            },
            {
              id: '1121',
              type: 'page',
              title: 'Work Spec',
            },
          ],
        },
      },
    ]
    
    function flatten(arr) {
      const flattened = []
      for (const { children, ...element } of arr) {
        flattened.push(element)
        if (children) {
          flattened.push(...flatten(children.page.results))
        }
      }
      return flattened
    }
    
    const flat = [{ page: { results: flatten(array[0].page.results) } }]
    
    console.log(flat)
    console.log(flat[0].page.results)
    
    
    // [
    //   {
    //     "page": {
    //       "results": [
    //         {
    //           "id": "1234",
    //           "type": "page",
    //           "title": "Deprecated Spec"
    //         },
    //         {
    //           "id": "5678",
    //           "type": "page",
    //           "title": "Deprecated | Cash Spec"
    //         },
    //         {
    //           "id": "9101",
    //           "type": "page",
    //           "title": "Deprecated | Ledger Spec"
    //         },
    //         {
    //           "id": "1121",
    //           "type": "page",
    //           "title": "Work Spec"
    //         }
    //       ]
    //     }
    //   }
    // ]