$elemMatch caches its state and never re-evaluates to false!
See original GitHub issueDescribe the bug
It seems that using $elemMatch
and ability.can()
from the useAbility
hook causes the first true
returned by ability.can()
to be applied to all subsequent can()
calls when iterating over an array of elements.
To Reproduce Steps to reproduce the behavior:
import { AbilityBuilder, Ability, AbilityClass } from '@casl/ability';
import { TeamFragment } from '../../generated/graphql';
import subjectTypeFromGraphql from './subjectTypeFromGraphql';
type Abilities = ['manage', 'Team' | TeamFragment];
type AppAbility = Ability<Abilities>;
export const AppAbility = Ability as AbilityClass<AppAbility>;
export default function defineAbilityFor() {
const { can, build } = new AbilityBuilder(AppAbility);
can('manage', 'Team', {
groupMembers: {
$elemMatch: {
'account.id': '8461e09d-7a54-4649-9427-28e71dff9e73'
'roles.roleId': 'admin',
},
},
});
return build({ detectSubjectType: subjectTypeFromGraphql });
}
import { detectSubjectType } from '@casl/ability';
export default (subject: any) => {
if (subject?.__typename) {
return subject.__typename;
}
return detectSubjectType(subject);
};
- How do you check abilities
I have an array of two Team
s. The first I should not be able to manage
, and the second I should. On first render, this is shown correctly. When the component re-renders, it’s incorrectly showing that both Teams
are now manage
able.
If I reverse the order of the array, both are shown as manage
able on first and additional renders. I believe the true
being returned by the ability.can('manage', team)
for the first item is being cached or memoized somewhere for the second, even though they are separate objects.
I’ve hardcoded the account id for simplicity at the moment.
Expected behavior
I expect each call of ability.can('manage', team)
in a loop to be specific the team
object that was passed in.
CASL Version
@casl/ability
- 4.1.6
@casl/react
- 2.1.1
Environment: Chrome 85, Typescript 3.9.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:10 (6 by maintainers)
Top GitHub Comments
It’s good! Thank you very much 😃
@martdavidson could you please check whether all good? The sift issue was closed