tw1742
tw1742

Reputation: 1484

How to handle when no search results are found using material-table with React and remote data

I'm using material-table with React using remote data. In cases when no search results are found I'm trying to sort out how to remove the display of the spinner and show the "No records to display". The search executes the web service call after each keystroke in the search field. I think what I'm after is to set a timeOut to stop the spinner, but I'm sure where to add this in the code below and am a bit confused in the syntax.

render() {
    return (
        <MaterialTable
            icons={tableIcons}
            title="Remote Data Preview"
            columns={[
                { title: 'Publication ID', field: 'publicationId' },
                { title: 'PMID', field: 'pmid' },
                { title: 'First author', field: 'firstAuthor' },
                { title: 'Publication', field: 'title' },
                { title: 'Journal', field: 'journal' },
                { title: 'Status', field: 'status' },
            ]}
            data={query =>
                new Promise((resolve, reject) => {
                    let url = GET_PUBLICATIONS_URL

                    if (query.search) {
                        url += query.search + '?pmid=true'

                        fetch(url)
                            .then(response => response.json())
                            .then(result => {
                                resolve({
                                    data: [result],
                                    page: 0,
                                    totalCount: 1,
                                })
                            }).catch(error => {
                            })
                    }
                    else {
                        console.log("** No PMID added...")
                        url += '?size=' + query.pageSize
                        url += '&page=' + (query.page)

                        fetch(url)
                            .then(response => response.json())
                            .then(result => {
                                resolve({
                                    data: result._embedded.publications,
                                    page: result.page.number,
                                    totalCount: result.page.totalElements,
                                })
                                console.log("** Data: ", result._embedded.publications);
                            }).catch(error => {
                                 setTimeout(resolve, 1000)
                                 return Promise.reject(error);
                            })
                    }
                })
            }
            options={{
                search: true
            }}
        />
    )
}

When no search results are returned using the above code the console shows:

Uncaught (in promise) SyntaxError: Unexpected token U in JSON at position 0 material-table.js:249 Uncaught (in promise) TypeError: Cannot read property 'totalCount' of undefined

Upvotes: 1

Views: 1910

Answers (1)

Sultan H.
Sultan H.

Reputation: 2938

What if we consider: extract Fetching Data from the data property for the table to a standard method, invoke it at the componentDidMount and remove the promise since it's not needed there, let's see if that would solve the problem:

componentDidMount(){
  this.getTableData();
}

getTableData = query => {
    let url = GET_PUBLICATIONS_URL;
    if (query.search) {
      url += query.search + '?pmid=true';

      fetch(url)
        .then(response => response.json())
        .then(result => {
          this.setState({
            tableData: {
              data: [result],
              page: 0,
              totalCount: 1,
            }
          })
        })
        .catch(error => {
          this.setState({
            error: {
              id: 2,
              error: error.message
            }
          })
        })
    } else {
      url += '?size=' + query.pageSize;
      url += '&page=' + (query.page);
      fetch(url)
        .then(response => response.json())
        .then(result => {
          this.setState({
            tableData: result._embedded.publications,
            page: result.page.number,
            totalCount: result.page.totalElements,
          })
        })
        .catch(error => {
          this.setState({
            error: {
              id: 2,
              error: error.message
            }
          })
        })
    }
}

render() {
  const { state: { tableData } } = this;

  return (
    <MaterialTable
      icons={tableIcons}
      title="Remote Data Preview"
      columns={[
          { title: 'Publication ID', field: 'publicationId' },
          { title: 'PMID', field: 'pmid' },
          { title: 'First author', field: 'firstAuthor' },
          { title: 'Publication', field: 'title' },
          { title: 'Journal', field: 'journal' },
          { title: 'Status', field: 'status' },
      ]}
      data={tableData.data}
      options={{search: true}}
    />
  )
}

Upvotes: 1

Related Questions