Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArrayInput in Filter claims mutators is required. #4095

Closed
octaltree opened this issue Dec 2, 2019 · 4 comments · Fixed by #4105
Closed

ArrayInput in Filter claims mutators is required. #4095

octaltree opened this issue Dec 2, 2019 · 4 comments · Fixed by #4105
Assignees
Labels

Comments

@octaltree
Copy link

What you were expecting:

The tutorial says filters are using *Input in Filter. I want to use ArrayInput in Filter with react-admin v3. Following App.js is working as expected with v2.

What happened instead:

I got message "Something went wrong" and this.

Uncaught Error: Array mutators not found. You need to provide the mutators from final-form-arrays to your form
    at useFieldArray (react-final-form-arrays.es.js:83)
    at ArrayInput (ArrayInput.js:89)
    at renderWithHooks (react-dom.development.js:16317)
    at mountIndeterminateComponent (react-dom.development.js:18800)
    at beginWork$1 (react-dom.development.js:20149)
    at HTMLUnknownElement.callCallback (react-dom.development.js:337)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
    at invokeGuardedCallback (react-dom.development.js:439)
    at beginWork$$1 (react-dom.development.js:25768)
    at performUnitOfWork (react-dom.development.js:24685)
    at workLoopSync (react-dom.development.js:24658)
    at performSyncWorkOnRoot (react-dom.development.js:24247)
    at react-dom.development.js:12285
    at unstable_runWithPriority (scheduler.development.js:701)
    at runWithPriority$2 (react-dom.development.js:12231)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
    at flushSyncCallbackQueue (react-dom.development.js:12268)
    at discreteUpdates$1 (react-dom.development.js:24401)
    at discreteUpdates (react-dom.development.js:1439)
    at dispatchDiscreteEvent (react-dom.development.js:5914)
useFieldArray @ react-final-form-arrays.es.js:83
ArrayInput @ ArrayInput.js:89
renderWithHooks @ react-dom.development.js:16317
mountIndeterminateComponent @ react-dom.development.js:18800
beginWork$1 @ react-dom.development.js:20149
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
beginWork$$1 @ react-dom.development.js:25768
performUnitOfWork @ react-dom.development.js:24685
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
index.js:1375 The above error occurred in the <ArrayInput> component:
    in ArrayInput (created by Field)
    in Field (created by FilterFormInput)
    in div (created by FilterFormInput)
    in FilterFormInput (created by FilterForm)
    in form (created by FilterForm)
    in FilterForm (created by ReactFinalForm)
    in ReactFinalForm (created by EnhancedFilterForm)
    in EnhancedFilterForm (created by Filter)
    in Filter (at App.js:9)
    in UserFilter (at App.js:18)
    in div (created by ForwardRef(Toolbar))
    in ForwardRef(Toolbar) (created by WithStyles(ForwardRef(Toolbar)))
    in WithStyles(ForwardRef(Toolbar)) (created by ListToolbar)
    in ListToolbar (created by ListView)
    in div (created by ListView)
    in ListView (created by List)
    in List (at App.js:18)
    in UserList (created by WithPermissions)
    in WithPermissions (created by Context.Consumer)
    in Route (created by ResourceRoutes)
    in Switch (created by ResourceRoutes)
    in ResourceRoutes (created by Resource)
    in Resource (at App.js:47)
    in Route (created by RoutesWithLayout)
    in Switch (created by RoutesWithLayout)
    in RoutesWithLayout (created by Context.Consumer)
    in div (created by Layout)
    in main (created by Layout)
    in div (created by Layout)
    in div (created by Layout)
    in Layout (created by WithStyles(Layout))
    in WithStyles(Layout) (created by Context.Consumer)
    in withRouter(WithStyles(Layout)) (created by ConnectFunction)
    in ConnectFunction (created by LayoutWithTheme)
    in ThemeProvider (created by LayoutWithTheme)
    in LayoutWithTheme (created by Context.Consumer)
    in Route (created by CoreAdminRouter)
    in Switch (created by CoreAdminRouter)
    in div (created by CoreAdminRouter)
    in CoreAdminRouter (created by Context.Consumer)
    in Route (created by AdminUI)
    in Switch (created by AdminUI)
    in AdminUI (created by Admin)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Context.Consumer)
    in ConnectedRouterWithContext (created by ConnectFunction)
    in ConnectFunction (created by AdminContext)
    in TranslationProvider (created by AdminContext)
    in Provider (created by AdminContext)
    in AdminContext (created by Admin)
    in Admin (at App.js:46)
    in App (at src/index.js:7)

React will try to recreate this component tree from scratch using the error boundary you provided, Layout.

Steps to reproduce:

As the tutorial, I installed react-admin and related libraries.

  "dependencies": {
    "prop-types": "^15.7.2",
    "ra-data-json-server": "^3.0.2",
    "react": "^16.12.0",
    "react-admin": "^3.0.2",
    "react-dom": "^16.12.0",
    "react-scripts": "3.2.0"
  },

I wrote App.js.

import React from 'react';
import { Admin, Resource, ListGuesser } from 'react-admin';
import { List, Datagrid, TextField, EmailField } from 'react-admin';
import { Create, SimpleForm, SimpleFormIterator, ArrayInput } from 'react-admin';
import { Filter } from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';

const UserFilter = (props) => (
    <Filter {...props}>
        <ArrayInput label="Array" source="afield">
            <SimpleFormIterator>
            </SimpleFormIterator>
        </ArrayInput>
    </Filter>
);

export const UserList = props => (
    <List {...props} filters={<UserFilter/>}>
        <Datagrid rowClick="edit">
            <TextField source="id" />
            <TextField source="name" />
            <TextField source="username" />
            <EmailField source="email" />
            <TextField source="address.street" />
            <TextField source="phone" />
            <TextField source="website" />
            <TextField source="company.name" />
        </Datagrid>
    </List>
);


export const UserCreate = props => ( // I can `ArrayInput` in SimpleForm.
    <Create {...props}>
        <SimpleForm>
            <ArrayInput source="afield">
                <SimpleFormIterator>
                </SimpleFormIterator>
            </ArrayInput>
        </SimpleForm>
    </Create>
);

const dataProvider = jsonServerProvider('http://jsonplaceholder.typicode.com');
const App = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="users" list={UserList} create={UserCreate} />
    </Admin>
);

export default App;

Related code:

insert short code snippets here

Other information:

Environment

  • React-admin version: 3.0.2
  • Last version that did not exhibit the issue (if applicable): 2.9.9 {"prop-types":"^15.7.2","ra-data-json-server":"2.9.9","react":"^16.12.0","react-admin":"2.9.9","react-dom":"^16.12.0","react-scripts":"3.2.0"}
  • React version:
  • Browser: chrome
  • Stack trace (in case of a JS error):

yarn.lock for 3.0.2
yarn.lock.txt

@fzaninotto
Copy link
Member

I don't understand the logic of using an ArrayInput in a FilterForm. What are you trying to achieve?

@octaltree
Copy link
Author

The API I use accepts complex queries.
I wrote as a prototype a filter and a data provider that input an array of (key, operator, value). This worked well with v2.9.8, but it stopped working after updating to v3.0.2.

var filters;
const MyFilter = props => {
  const dummySetFilters =
    props.context === 'form'
      ? o => {
          filters = o;
        }
      : props.setFilters;
  const operators = [
    {id: 'eq', name: '='},
    {id: 'gt', name: '>'},
    {id: 'gte', name: '>='},
    {id: 'lt', name: '<'},
    {id: 'lte', name: '<='},
    {id: 'neq', name: '<> or !='},
    {id: 'like', name: 'LIKE'},
    {id: 'ilike', name: 'ILIKE'},
    {id: 'in', name: 'IN'},
    {id: 'is', name: 'IS'},
    {id: 'fts', name: '@@'},
    {id: 'plfts', name: '@@'},
    {id: 'phfts', name: '@@'},
    {id: 'wfts', name: '@@'},
    {id: 'cs', name: '@>'},
    {id: 'cd', name: '<@'},
    {id: 'ov', name: '&&'},
    {id: 'sl', name: '<<'},
    {id: 'sr', name: '>>'},
    {id: 'nxr', name: '&<'},
    {id: 'nxl', name: '&>'},
    {id: 'adj', name: '-|-'},
    {id: 'not', name: 'NOT'}
  ];
  return (
    <Filter {...props} setFilters={dummySetFilters}>
      <ArrayInput label="Filters" source="conditions" alwaysOn>
        <SimpleFormIterator>
          <TextInput source="key" />
          <SelectInput source="op" choices={operators} />
          <TextInput source="val" />
        </SimpleFormIterator>
      </ArrayInput>
      <button alwaysOn onClick={() => props.setFilters(filters)}>
        Search
      </button>
    </Filter>
  );
};

@fzaninotto
Copy link
Member

O_o

I didn't even imagine this was possible, but that's a smart usage of ArrayInput! I'll do my best to make it work again in 3.0, thanks for the report.

@octaltree
Copy link
Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants