Search code examples
reactjsgraphqlapolloreact-apolloreact-select

React-Select with React-Apollo does not work


We are using react-select and fetching the items as the user types. I am not able to make it work with react-apollo.

Can someone help me provide a guideline?

Here is my unsuccessful attempt:

class PatientSearchByPhone extends Component {
  updateProp = mobile => {
    if (mobile.length < 10) return;
    this.props.data.refetch({ input: { mobile } });
  };

  render() {
    console.log(this.props.data);
    return <AsyncSelect cacheOptions loadOptions={this.updateProp} />;
  }
}

const FETCH_PATIENT = gql`
  query Patient($input: PatientSearchInput) {
    getPatients(input: $input) {
      id
      first_name
    }
  }
`;
export default graphql(FETCH_PATIENT, {
  options: ({ mobile }) => ({ variables: { input: { mobile } } })
})(PatientSearchByPhone);

Versions:
"react-apollo": "^2.1.11",
"react-select": "^2.1.0"

Thanks for your time.


Solution

  • I got an e-mail asking a response to this question. It reminds me of this XKCD comics:

    Never have I felt so close to another soul

    I do not recall the exact solution I implemented, so I setup a complete example for this.

    This app (code snippet below) kickstarts searching as soon as you type 4 characters or more in the input box (You are expected to type artist's name. Try vinci?). Here is the code:

    import React, { useState } from "react";
    import "./App.css";
    import AsyncSelect from "react-select/async";
    import ApolloClient, { gql } from "apollo-boost";
    
    const client = new ApolloClient({
      uri: "https://metaphysics-production.artsy.net"
    });
    
    const fetchArtists = async (input: string, cb: any) => {
      if (input && input.trim().length < 4) {
        return [];
      }
      const res = await client.query({
        query: gql`
          query {
            match_artist(term: "${input}") {
              name
              imageUrl
            }
          }
        `
      });
    
      if (res.data && res.data.match_artist) {
        return res.data.match_artist.map(
          (a: { name: string; imageUrl: string }) => ({
            label: a.name,
            value: a.imageUrl
          })
        );
      }
    
      return [];
    };
    
    const App: React.FC = () => {
      const [artist, setArtist] = useState({
        label: "No Name",
        value: "https://dummyimage.com/200x200/000/fff&text=No+Artist"
      });
      return (
        <div className="App">
          <header className="App-header">
            <h4>Search artists and their image (type 4 char or more)</h4>
            <AsyncSelect
              loadOptions={fetchArtists}
              onChange={(opt: any) => setArtist(opt)}
              placeholder="Search an Artist"
              className="select"
            />
            <div>
              <img alt={artist.label} src={artist.value} className="aimage" />
            </div>
          </header>
        </div>
      );
    };
    
    export default App;
    

    You can clone https://github.com/naishe/react-select-apollo it is a working example. I have deployed the app here: https://apollo-select.naishe.in/, may be play a little?