Repository: angular/angular
File: devtools/projects/ng-devtools-backend/src/lib/router-tree.ts (TypeScript)

Code before:
      for (const el in child.data) {
        if (child.data.hasOwnProperty(el)) {
          routeConfig?.data?.push({
            key: el,
            value: child.data[el],
          });
        }
      }
    }

    return routeConfig;
  });
}

function getFunctionName(fn: Function) {
  const isArrow = !fn.hasOwnProperty('prototype');
  if (isArrow) return '[Function]';
  return fn.name === 'redirectTo' ? '[Function]' : fn.name;
}

function getRedirectToName(child: AngularRoute) {
  if (child.redirectTo instanceof Function) {
    return getFunctionName(child.redirectTo);
  }

  return `${child.path} -> redirecting to -> "${child.redirectTo}"`;
}

function childRouteName(child: AngularRoute): string {
  if (child.component) {
    return child.component.name;
  } else if (child.loadChildren || child.loadComponent) {
    return `${child.path} [Lazy]`;
  } else {
    return 'no-name-route';
  }
}

/**
 *  Get the element reference by type & name from the routes array. Called recursively to search through all children.
 * @param type - type of element to search for (canActivate, canActivateChild, canDeactivate, canLoad, providers, redirectTo)
 * @param routes - array of routes to search through
 * @param name - name of the element to search for refers to the name of the guard or provider
 * @returns - the element reference if found, otherwise null
 */
export function getElementRefByName(
  type: RoutePropertyType,
  routes: AngularRoute[],
  name: string,
): any | null {
  for (const element of routes) {

Review comment (suggestion):
Given there is now a separate property, we don't need to be that descriptive with `{path} -> redirecting to -> {redirectTo}`. I think that displaying just `redirectTo` should be enough.

Code after:
    if (childDescendents) {
      routeConfig.children = assignChildrenToParent(routeConfig.path, childDescendents, currentUrl);
    }

    if (child.data) {
      for (const el in child.data) {
        if (child.data.hasOwnProperty(el)) {
          routeConfig?.data?.push({
            key: el,
            value: child.data[el],
          });
        }
      }
    }

    return routeConfig;
  });
}

/**
 * Get the display name for a function or class.
 * @param fn - The function or class to get the name from
 * @param defaultName - Optional name to check against. If the function name matches this value,
 * '[Function]' is returned instead
 * @returns The formatted name: class name, function name with '()', or '[Function]' for anonymous/arrow functions
 */
function getClassOrFunctionName(fn: Function, defaultName?: string) {
  const isArrowWithNoName = !fn.hasOwnProperty('prototype') && fn.name === '';

  if (isArrowWithNoName) {
    return '[Function]';
  }

  const hasDefaultName = fn.name === defaultName;
  if (hasDefaultName) {
    return '[Function]';
  }

  // Check if it's a class by examining the function's string representation
  const isClass = /^class\s/.test(fn.toString());

  // Return class name without parentheses, function name with parentheses
  return isClass ? fn.name : `${fn.name}()`;
}

function getPropertyName(child: AngularRoute, property: 'title' | 'redirectTo') {
  if (child[property] instanceof Function) {
    return getClassOrFunctionName(child[property], property);
  }

  return child[property];