How to prevent get request from being send if the length of the query field is short in react-admin
Asked Answered
B

1

7

I'm using react-admin and trying to create a filter with autocomplete field that will make a query as I type and will only start sending the query when the search criteria length is longer then 2.

I'm currently using shouldRenderSuggestions inside of my AutocompleteInput field but this still send two requests with an empty string in the "nickname" filter, this is the code part:

<AutocompleteInput optionText="nickname" shouldRenderSuggestions={(val) => {
        return val.trim().length > 2
      }}/>

The thing that happens is when I fill in the first and second letters the GET request is sent but with an empty string in the nickname field,

The string input is for example:"abc":

1ST request: http://website.loc/clients?filter={"nickname":""}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

2ND request: http://website.loc/clients?filter={"nickname":""}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

3RD request: http://website.loc/clients?filter={"nickname":"abc"}&page=1&perPage=25&range=[0,24]&sort=["id","DESC"]

I want to avoid from sending the first two requests entirely.

The full code of the component:

const PostPagination = props => (
  <Pagination rowsPerPageOptions={[]} {...props} />
);

const PostFilter = (props) => (
  <Filter {...props}>
    <ReferenceInput label="Client"
                    source="client_id"
                    reference="clients"
                    allowEmpty
                    filterToQuery={searchText => ({ nickname: searchText })}>
      <AutocompleteInput optionText="nickname" shouldRenderSuggestions={(val) => {
        return val.trim().length > 2
      }}/>
    </ReferenceInput>
  </Filter>
);

const PostsList = props => {
  return (
    <List {...props} perPage={15}
          pagination={<PostPagination/>}
          filters={<PostFilter/>}
          exporter={false}>
      <Datagrid>
        <TextField source="nickname" sortable={false}/>
        <DateField label="Created" source="created_at" showTime/>
      </Datagrid>
    </List>
  );
};

Edit: same question goes for "search-as-you-type" fields like <TextInput> inside a <Filter> field, I started to ask a new question but realized it will be kind of a duplicate,

This is the code that also sends requests starting from 1 char, in this case there isn't even a shouldRenderSuggestions option to force it to send empty requests

const ClientFilter = (props) => (
  <Filter {...props}>
    <TextInput label="Search" source="str" alwaysOn/>
  </Filter>
);

Live example of code in codesandbox.io

Bloodline answered 11/3, 2019 at 10:11 Comment(1)
It shouldn't make that many requests. What version of react-admin are you using? Can you set up a codesandbox showcasing the issue ?Photochromy
A
1

I stumbled upon this issue, too. The best I've come up with so far is a small wrapper component that prevents the ReferenceInput from triggering API requests unless a certain condition is met:

  const ConditionalFilter = (props) => {
    const { children, condition, setFilter } = props;
    const conditionalSetFilter = (val) => {
      if (setFilter && condition(val)) setFilter(val);
    };
    return React.cloneElement(children, { ...props, setFilter: conditionalSetFilter });
  };

Used like this:

  const condition = val => val.trim().length > 2;
  return (
    <ReferenceInput 
      source="…"
      reference="…"
      shouldRenderSuggestions={condition}
    >
      <ConditionalFilter condition={condition}>
        <AutocompleteInput />
      </ConditionalFilter>
    </ReferenceInput>
  );

Update for react-admin v3: (without the wrapper component, which is no longer necessary/useful)

const condition = (val) => !!val && val.trim().length > 2;
return (
  <ReferenceInput
    source="…"
    reference="…"
    filterToQuery={(val) => (condition(val) ? { name: val.trim() } : {})}
  >
    <AutocompleteInput shouldRenderSuggestions={condition} />
  </ReferenceInput>
);
Ambi answered 30/8, 2019 at 16:56 Comment(1)
I was hoping to get an official answer by Gildas Garcia but your answer did the trick, Thanks.Bloodline

© 2022 - 2024 — McMap. All rights reserved.