I have a React component made for hiding or showing content depending on the user's permissions. The permissions are received from a API via a hook created with redux toolkit and RTK Query API.
Permission.tsx:
import type { ReactElement } from 'react';
import { useHasPermissionQuery } from '~/common/authSlice';
type PermissionProps = {
action: string;
resource: string;
element?: React.ReactNode | null;
};
const Permission = ({ action, resource, element }: PermissionProps): ReactElement | null => {
const {
data: hasPermission,
isError,
isFetching,
} = useHasPermissionQuery({
action: action,
resource: resource,
});
console.log(`${resource}.${action}: ${hasPermission ?? false ? 'yes' : 'no'}`);
if (hasPermission === undefined || !hasPermission || isError || isFetching) {
return <div>Not allowed</div>;
}
return <>{element}</>;
};
export default Permission;
The component is used like this, with the ApiProvider from redux toolkit. I haven't configured any custom stores.:
const domContainer = document.getElementById('view-main')!;
const root = ReactDOM.createRoot(domContainer);
root.render(
<ApiProvider api={api}>
<Permission
action="dummyAction"
resource="dummyResource"
element={<div>Is this allowed?</div>}
/>
</ApiProvider>
);
authSlice.ts:
import { api } from '~/features/posts/postsSlice';
export type Permission = boolean;
export type PermissionRequest = {
action: string;
resource: string;
};
export const api = api.createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
endpoints: (build) => ({
hasPermission: build.query<Permission, PermissionRequest>({
query: ({ action, resource }) =>
`authorization/testpermission/?requestedAction=${action}&resource=${resource}`,
}),
}),
});
export const { useHasPermissionQuery } = extendedApiSlice;
This is the console log of the Permission component. The final log says that the user has the permission, but that's not what the network log says, as you can see in the other picture.
So I'm not sure what's happening here. Everything from the server is fine, so is it the hooks or the component where something is not right?
I think your hasPermission
variable is the complete response of the server (instead of the boolean value you are expecting in your code):
console.log(hasPermission) // { hasPermission: false }
Use the correct value using:
const {
data,
isError,
isFetching,
} = useHasPermissionQuery({
action: action,
resource: resource,
});
const hasPermission = data.hasPermission
Or same, using double destructuring:
const {
data: { hasPermission },
isError,
isFetching,
} = useHasPermissionQuery({
action: action,
resource: resource,
});