react-admin
react-admin copied to clipboard
fix: ReferenceArrayInput might pass non-array to children as values
I noticed that when you use multiple Filters using the same resource (or a sub-property) and one uses a ReferenceArrayInput, it might receive its value from another filter. When this is not an array, it will crash, at it will assume that the value is an array.
E.g. consider these filters:
<ReferenceInput label="School" source="user.school" reference="School">
<AutocompleteInput {... some props} />
</ReferenceInput>
<ReferenceArrayInput label="Teacher" source="user" reference="User">
<AutocompleteInput {... some props} />
</ReferenceArrayInput>
the second one will receive a value of { school: { id: "some-schoolId", ...}} and therefore crash
The quickfix is to define a format, altough this is not so obvious.
format={(e) => {
if (Array.isArray(e)) {
return e;
}
return [];
}}
I think it makes sense to define that as default for ReferenceArrayInput as they assume that if they have a non-falsy value, it is an array.
Thanks for your contribution. Would you mind opening an issue first with a link to a codesandbox showing the problem ?
@macrozone Hi, thanks for opening this PR. We need to understand better what you want to achieve with this PR. Could you open a linked issue containing a Code Sandbox in order to show the bug?
@Luwangel the problem is that react-admin (or underlying form library) mixes up sources like source="user.school" or source="user.role"`. There is a hook as far as i remember that returns a vallue based on the source. This hook mixes up the sources when there is a dot in the source name.
The proper solution would probably be to guarantee that source with dot notation are completly independent from each other.
My Pull request does not fix that, but fixes a runtime error that might occures because of this underlying problem. ReferenceArrayInput seems not to check whether a value is actually an array and tries to call array operations on it.
So there are actually two flaws:
- ReferenceArrayInput does not sanitize the value
- values leak into other inputs when there is dot notation
I failed to fix these as the code is quite complex, but defining default formatting at least sanitizes the value in the default case.