0

I have a nested Object that I need to iterate. The object looks like this:

{
    "Page1": {
        "path": "/page1"
    },
    "Page2": {
        "path": "/account/menu/page1"
    },
    "Page3": {
        "items": {
            "Subpage1": {
                "path": "/account/menu/subpage1"
            },
            "Subpage2": {
                "path": "/account/menu/subpage2"
            },
            "Subpage3": {
                "path": "/account/menu/subpage3"
            }
        }
    },
    "Page4": {
        "items": {
            "Subpage4": {
                "path": "/account/menu/subpage4"
            },
            "Subpage5": {
                "path": "/account/menu/subpage5"
            },
...

I need to get the name of the specific subpage, based on the path of the user.

For example. If the user is on the page /account/menu/subpage2. I need to get the name Subpage2.

What I did is the following:

const currentPageName = getPageName(this.props?.match?.params.menu); //This function gets the name of the current page (Subpage2)


const getThePageName = = path => Object.keys(jsonData).find(el => jsonData[el]?.items && jsonData[el]?.items[currentPageName]?.path === path)

console.log("getThePageName", getThePageName("/account/menu/subpage2")));

The result of the above is Page3, but I need it to be Subpage2. What am I doing wrong and how to fix it?

pilchard
  • 12,414
  • 5
  • 11
  • 23
Pikk
  • 2,343
  • 6
  • 25
  • 41
  • Can subpage contains another nested subpages? – holydragon Jun 24 '22 at 08:34
  • also: [Access object child properties using a dot notation string](https://stackoverflow.com/questions/8051975/access-object-child-properties-using-a-dot-notation-string) – pilchard Jun 24 '22 at 08:35
  • @holydragon no, there are only 2 levels of pages. Pages and subpage. No deeper pages. – Pikk Jun 24 '22 at 08:44
  • 2
    @pilchard those two links do not fit my needs, because in both of them I would need to provide the full path. For example `Page3.items.subpage2`. Here I don't know if a person is vising a subpage in menu `Page3` or menu `Page4`. They both have subpages. – Pikk Jun 24 '22 at 08:51
  • You're right, I didn't read closely enough. – pilchard Jun 24 '22 at 09:17

3 Answers3

2

Concept

Iterate through all the data entries and check if the path of any of these pages equal to the target path specified. Also within the loop, iterate through all of the pages' subpages and, again, check if the path of any of these subpages equal to the target path specified. If a match found then return the result as the key of the path's object.

Code

const data = {"Page1":{"path":"/page1"},"Page2":{"path":"/account/menu/page1"},"Page3":{"items":{"Subpage1":{"path":"/account/menu/subpage1"},"Subpage2":{"path":"/account/menu/subpage2"},"Subpage3":{"path":"/account/menu/subpage3"}}},"Page4":{"items":{"Subpage4":{"path":"/account/menu/subpage4"},"Subpage5":{"path":"/account/menu/subpage5"}}}};

function findPage(data,target){
  let result;
  Object.entries(data).forEach(page => {
    if (page[1].path === target) result = page[0];
    if (page[1].items){
      Object.entries(page[1].items).forEach(subpage => {
        if (subpage[1].path === target) result = subpage[0];
      });
    }
  });
  return result;
}

console.log(findPage(data,"/account/menu/subpage2"));
console.log(findPage(data,"/page1"));
holydragon
  • 6,158
  • 6
  • 39
  • 62
2

Solution using recursion, can work with deeper level of "sub pages".

const data = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, "Subpage6": { "items": { "Subsubpage1": { "path": "/secret" } } } } } };

function getPageNameForPath(data, path) {
  for (const pageName in data) {
    if (data[pageName].path != null) {
      if (data[pageName].path === path) {
        return pageName;
      }
    } else {
      const found = getPageNameForPath(data[pageName].items, path);
      if (found) {
        return found;
      }
    }
  }
}

console.log(getPageNameForPath(data, '/account/menu/subpage2'));
console.log(getPageNameForPath(data, '/account/menu/page1'));
console.log(getPageNameForPath(data, '/secret'));
pilchard
  • 12,414
  • 5
  • 11
  • 23
UnitTset
  • 259
  • 1
  • 5
1

here is some piece of code

const jsonData = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, } } };

const currentPageName = 'Subpage2';

const getThePageName = path => Object.keys(jsonData).reduce((acc, el) => {
  if (acc?.length) {
    return acc;
  }
  if (jsonData[el].hasOwnProperty('items')) {
    if (jsonData[el]?.items?.[currentPageName]?.path === path) {
      console.log(path, jsonData[el]?.items?.[currentPageName]?.path)
      acc = currentPageName;
    }
  } else {
    if (jsonData[el].path === path) {
      console.log(path, jsonData[el].path, path)
      acc = el;
    }
  }
  return acc;
}, undefined);

console.log("getThePageName", getThePageName("/account/menu/subpage2"));
pilchard
  • 12,414
  • 5
  • 11
  • 23
Mohit Sharma
  • 622
  • 6
  • 11