Steams / ra-data-hasura-graphql

React-admin data provider for Hasura GraphQL endpoints
MIT License
211 stars 33 forks source link

AutocompleteInput error: Cannot read property 'type' of undefined #62

Open dat7e opened 4 years ago

dat7e commented 4 years ago

Hello. First of all thanks for your works on this great package, it's a very quick way to hook up an admin interface to a Hasura-powered API.

I'm currently trying to make a form where user can choose a referenced item (simple one-to-one relationship) from a fairly large list (>200 items). Using SelectInput wouldn't cut it since it only displays 25 items by default and cannot be searched on. So my solution was to swap out SelectInput for AutocompleteInput. The component displays data fine at first, and I can also choose other values, but throws and error when I try searching for an item. In the requests tab, it doesn't seem like it's sending any search request to the Hasura backend.

ra-hasura-autocomplete-input

Reproduce: Step 1: Clone https://github.com/cpursley/react-admin-low-code Step 2: In todos.tsx, replace instances of SelectInput with AutocompleteInput Step 3: Run the project, browse to edit todo page and interact with the autocomplete input box.

I can reproduce this in both my code and the example project above. Maybe it's something I overlooked? Help would be very appreciated. Thank you!

dtuite commented 3 years ago

I have hit this problem too. I would really appreciate a workaround if anyone knows of one. The stacktrace isn't very helpful but I'm attaching it here anyway. Please let me know if there is any other info I can add to help debug this.


console.<computed> | @ | index.js:1
-- | -- | --
  | printWarning | @ | warning.js:34
  | warning | @ | warning.js:57
  | warn | @ | index.js:26
  | push../node_modules/node-polyglot/index.js.Polyglot.t | @ | index.js:369
  | translate | @ | index.js:41
  | (anonymous) | @ | useTranslate.js:25
  | Notification | @ | Notification.js:69
  | renderWithHooks | @ | react-dom.development.js:14985
  | updateFunctionComponent | @ | react-dom.development.js:17356
  | beginWork | @ | react-dom.development.js:19063
  | beginWork$1 | @ | react-dom.development.js:23940
  | performUnitOfWork | @ | react-dom.development.js:22776
  | workLoopSync | @ | react-dom.development.js:22707
  | renderRootSync | @ | react-dom.development.js:22670
  | performSyncWorkOnRoot | @ | react-dom.development.js:22293
  | (anonymous) | @ | react-dom.development.js:11327
  | unstable_runWithPriority | @ | scheduler.development.js:646
  | runWithPriority$1 | @ | react-dom.development.js:11276
  | flushSyncCallbackQueueImpl | @ | react-dom.development.js:11322
  | flushSyncCallbackQueue | @ | react-dom.development.js:11309
  | batchedUpdates$1 | @ | react-dom.development.js:22387
  | notify | @ | Subscription.js:19
  | notifyNestedSubs | @ | Subscription.js:90
  | handleChangeWrapper | @ | Subscription.js:95
  | dispatch | @ | redux.js:222
  | (anonymous) | @ | middleware.js:22
  | (anonymous) | @ | redux-saga-core.esm.js:1410
  | dispatch | @ | redux.js:638
  | (anonymous) | @ | io-6de156f3.js:133
  | (anonymous) | @ | redux-saga-core.esm.js:472
  | exec | @ | redux-saga-core.esm.js:31
  | flush | @ | redux-saga-core.esm.js:87
  | asap | @ | redux-saga-core.esm.js:46
  | runPutEffect | @ | redux-saga-core.esm.js:468
  | runEffect | @ | redux-saga-core.esm.js:1204
  | digestEffect | @ | redux-saga-core.esm.js:1271
  | next | @ | redux-saga-core.esm.js:1161
  | currCb | @ | redux-saga-core.esm.js:1251
  | Promise.then (async) |   |  
  | resolvePromise | @ | redux-saga-core.esm.js:395
  | runCallEffect | @ | redux-saga-core.esm.js:527
  | runEffect | @ | redux-saga-core.esm.js:1204
  | digestEffect | @ | redux-saga-core.esm.js:1271
  | next | @ | redux-saga-core.esm.js:1161
  | proc | @ | redux-saga-core.esm.js:1108
  | (anonymous) | @ | redux-saga-core.esm.js:585
  | immediately | @ | redux-saga-core.esm.js:56
  | runForkEffect | @ | redux-saga-core.esm.js:584
  | runEffect | @ | redux-saga-core.esm.js:1204
  | digestEffect | @ | redux-saga-core.esm.js:1271
  | next | @ | redux-saga-core.esm.js:1161
  | proc | @ | redux-saga-core.esm.js:1108
  | (anonymous) | @ | redux-saga-core.esm.js:585
  | immediately | @ | redux-saga-core.esm.js:56
  | runForkEffect | @ | redux-saga-core.esm.js:584
  | runEffect | @ | redux-saga-core.esm.js:1204
  | digestEffect | @ | redux-saga-core.esm.js:1271
  | next | @ | redux-saga-core.esm.js:1161
  | currCb | @ | redux-saga-core.esm.js:1251
  | takeCb | @ | redux-saga-core.esm.js:503
  | put | @ | redux-saga-core.esm.js:339
  | (anonymous) | @ | redux-saga-core.esm.js:376
  | exec | @ | redux-saga-core.esm.js:31
  | flush | @ | redux-saga-core.esm.js:87
  | asap | @ | redux-saga-core.esm.js:46
  | chan.put | @ | redux-saga-core.esm.js:375
  | (anonymous) | @ | redux-saga-core.esm.js:1412
  | (anonymous) | @ | useGetMatchingReferences.js:13
  | (anonymous) | @ | hooks.js:29
  | invokePassiveEffectCreate | @ | react-dom.development.js:23487
  | callCallback | @ | react-dom.development.js:3945
  | invokeGuardedCallbackDev | @ | react-dom.development.js:3994
  | invokeGuardedCallback | @ | react-dom.development.js:4056
  | flushPassiveEffectsImpl | @ | react-dom.development.js:23574
  | unstable_runWithPriority | @ | scheduler.development.js:646
  | runWithPriority$1 | @ | react-dom.development.js:11276
  | flushPassiveEffects | @ | react-dom.development.js:23447
  | (anonymous) | @ | react-dom.development.js:23324
  | workLoop | @ | scheduler.development.js:590
  | flushWork | @ | scheduler.development.js:545
  | performWorkUntilDeadline | @ | scheduler.development.js:157
dtuite commented 3 years ago

I figured it out.

Basically, when the combination of ReferenceInput and AutocompleteInput needs to get a list of Autocomplete suggestions from the GraphQL API, it sends the q param to the server to tell it how to filter.

However, you probably don't have an attribute named q on your model so the search throws an error.

The workaround is to override the filterToQuery property on <ReferenceInput />. In this case, name is a valid attribute on my model that I want to use for filtering.

<ReferenceInput
  source="company_id"
  reference="companies"
  sort={{ field: 'name', order: 'ASC' }}
  filterToQuery={(searchText) => ({ name: searchText })}
>
  <AutocompleteInput source="name" optionText="name" />
</ReferenceInput>