Is there a way to access staticData
in beforeLoad
?
#2089
-
Currently we use Is there a way to access Or to state it in another way, is there a function to access the current matches, similar to |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 7 replies
-
I'm looking for the exact same thing! It would be awesome if we can access the entire route object in import { AnyRoute, createRouter } from "@tanstack/react-router";
export const iterateRouteTree = <T>(
rootRoute: AnyRoute,
callback: (route: AnyRoute) => false | T
): T[] => {
const tempRouter = createRouter({
routeTree: rootRoute,
});
tempRouter.buildRouteTree();
const result: T[] = [];
const stack: AnyRoute[] = [tempRouter.routeTree];
while (stack.length > 0) {
const currentRoute = stack.pop();
if (currentRoute) {
const parsedData = callback(currentRoute);
if (parsedData) {
result.push(parsedData);
}
const children = currentRoute?.children as AnyRoute[];
if (children && children.length > 0) {
children.forEach((child) => {
stack.push(child);
});
}
}
}
return result;
}; Just put your generated route tree into this and you can ieterate through it and do whatever you want with a callback function. import { routeTree } from "@/routeTree.gen";
import { iterateRouteTree } from "./iterateRouteTree";
let permissionsMap: Map<string, string[]> | null = null;
const generatePermissionsMap = () => {
const iterateResult = iterateRouteTree<[string, string[]]>(routeTree, (route) => {
const { fullPath } = route;
const { requiredPermissions = [] } = route.options.staticData ?? {};
return [fullPath, requiredPermissions];
});
permissionsMap = new Map<string, string[]>(iterateResult);
};
export const getPermissionsMap = () => {
if (!permissionsMap) {
generatePermissionsMap();
}
return permissionsMap;
}; Then you might put it into the router context therefore you can access it from router.routesByPath[location.pathname] I'm currently using this |
Beta Was this translation helpful? Give feedback.
-
I also need this badly. |
Beta Was this translation helpful? Give feedback.
-
I wrote a small version import { Route } from './routes/__root';
import { BeforeLoadContext } from '@tanstack/react-router/dist/esm/route';
import { createRoute } from '@tanstack/react-router';
class PermissionCheckError extends Error {
constructor(permission: string) {
super(`Missing permission: ${permission}`);
this.name = 'PermissionCheckError';
}
}
type RouteOptions = (typeof Route)['options'];
function withPermissions<T extends RootRouteContext>(
beforeLoad?: (this: RouteOptions, ctx: BeforeLoadContext<void, void, T>) => Promise<T> | T | void,
) {
return function beforeLoadWrapped(this: RouteOptions, ctx: BeforeLoadContext<void, void, T>) {
if (this.staticData?.permissions?.length) {
const permissions = ctx.context.queryClient /*.getPermissions()*/ ?? [''];
const missingPermission = this.staticData.permissions.find((p) => !permissions.includes(p));
if (missingPermission) {
throw new PermissionCheckError(missingPermission);
}
}
return beforeLoad?.call(this, ctx);
};
}
const Route = createRoute({
staticData: {
permissions: ['write:clusters'],
},
getParentRoute: () => ...,
path: '...',
beforeLoad: withPermissions((_ctx) => {
// do whatever you would do inside the beforeLoad function
}),
// [...]
}); |
Beta Was this translation helpful? Give feedback.
-
I assume this discussion can be closed now, given that beforeLoad has access to the route matches? |
Beta Was this translation helpful? Give feedback.
I assume this discussion can be closed now, given that beforeLoad has access to the route matches?