Search code examples
node.jsobjectmultidimensional-arraymenu

Data structure for a console menu in Node.js with nested options that can be navigated backwards


I've been looking at ways to store and navigate a short nested / multi-level menu structure in Node.js.

  • I don't want to display all the options at once, I want to display each submenu independently as the user makes their choices.

  • Which means I also want to offer an option to backtrack to the previous submenu.

I had a look at storing the data in a nested array containing multiple objects. Then, using the array's intrinsic indexing, determine the parent menu. After researching for a while I couldn't find any simple method akin to menu[0].options[1].options[0].getParent() and obtain menu[0].options[1]. I want to make this flexible and reusable, so don't think using regular expressions is a good idea.

All the answers I was able to find revolved around crawling the entire array to match the pieces of the 'path' and then rebuild them, like this or this. I feel like this is overly complicated for the purpose so I looked into a more declarative, flatter data structure:

const menu = [
  { id: 1, name: 'Menu - Choose food', parentId: null },
  { id: 2, name: 'Fuit', parentId: null },
  { id: 3, name: 'Fruit Submenu: Orange', parentId: 2 },
  { id: 4, name: 'Fruit Submenu: Apple', parentId: 2 },
  { id: 5, name: 'Apple Submenu: Gala', parentId: 4 },
  { id: 6, name: 'Apple Submenu: Fuji', parentId: 4 },
  { id: 7, name: 'Apple Submenu: Golden', parentId: 4 },
  { id: 8, name: 'Vegetables', parentId: null },
  { id: 9, name: 'Vegetables Submenu: Cabbage', parentId: 8 },
  { id: 10, name: 'Vegetables Submenu: Carrot', parentId: 8 },
  { id: 11, name: 'Animal products', parentId: null },
  { id: 12, name: 'AP: Honey', parentId: 11 },
  { id: 13, name: 'AP: Milk', parentId: 11 },
  { id: 14, name: 'AP: Eggs', parentId: 11 }
];

What I don't like about this is that I have to explicitly declare the parent for each option, when that could be otherwise derived from the data structure in a nested setting.

My question is, considering the short and simple nature of this menu structure, what is the solution that makes the most sense to apply to be able to navigate backwards, the first or the second?

As a third option would it be correct to parse the menu structure into an XML document and use the DOM property parentElement, or is this like shooting a fly with a cannon?

// Parse XML string into a DOM document
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

// Get the item with ID '3' (example)
const itemId = '3';
const item = xmlDoc.querySelector(`item[id="${itemId}"]`);

// Access the parent node using parentElement
const parent = item.parentElement;
console.log(parent); // Output: Parent node of item with ID '3'

Is there a better alternative I wasn't able to find?


Solution

  • I found this example https://stackoverflow.com/a/71755733 using a Class to establish relationships between 'page nodes'.

    It creates a fair bit of code, but it makes sense.

    I would still be interested in more compact alternatives, if anyone knows any.