I have an array of objects with unknown nesting depth (it can be 5 or even more) like this:
const routes: routeType[] = [
{
path: '/user', visible: true, title: 'User'
},
{
path: "/admin", visible: true, title: "Admin", children: [
{index: true, visible: false},
{path: "dashboard", visible: true, title: "Dashboard"},
{path: "changelog", visible: true, title: "Changelog"},
{path: "profile", visible: true, title: "Profile"},
{path: "settings", visible: true, title: "Settings", children: [
{index: true, visible: false},
{path: "themes", visible: true, title: "Theme"}
{path: "themes/new", visible: true, title: "New"}
]
}
]
}]
The result I would like to obtain is a String Record composed in this way:
const resultMap: Record<string, string> = {
"/admin": "Admin",
"/admin/dashboard": "Dashboard",
"/admin/changelog": "Changelog",
"/admin/profile": "Profile",
"/admin/settings": "Settings",
"/admin/settings/themes": "Themes",
"/admin/settings/themes/new": "New"}
So:
There are many similar questions but none that match my needs. I struggled for two days but in the end I couldn't find a solution. Can you help me?
Thanks in advance!
A simple recursive function is your friend here. Just add the correct type annotations and you're good to go.
function buildStringRecord(
routes: RouteType[],
parentPath: string = '',
resultMap: Record<string, string> = {}
): Record<string, string> {
for (const route of routes) {
if (route.visible) {
const fullPath = parentPath + route.path;
if(route.title) {
resultMap[fullPath] = route.title;
}
if (route.children) {
buildStringRecord(route.children, fullPath + '/', resultMap);
}
}
}
return resultMap;
}
const resultMap = buildStringRecord(routes);
Working Example:
const routes = [ { path: '/user', visible: true, title: 'User', }, { path: '/admin', visible: true, title: 'Admin', children: [ { index: true, visible: false }, { path: 'dashboard', visible: true, title: 'Dashboard' }, { path: 'changelog', visible: true, title: 'Changelog' }, { path: 'profile', visible: true, title: 'Profile' }, { path: 'settings', visible: true, title: 'Settings', children: [ { index: true, visible: false }, { path: 'themes', visible: true, title: 'Theme' }, { path: 'themes/new', visible: true, title: 'New' } ] } ] }];
function buildStringRecord(
routes,
parentPath = "",
resultMap = {}
) {
for (const route of routes) {
if (route.visible) {
const fullPath = parentPath + route.path;
if(route.title) {
resultMap[fullPath] = route.title;
}
if (route.children) {
buildStringRecord(route.children, fullPath + '/', resultMap);
}
}
}
return resultMap;
}
const resultMap = buildStringRecord(routes);
console.log(resultMap);