Home > database >  Downloading file onClick is downloading on refresh
Downloading file onClick is downloading on refresh

Time:12-01

In my documents table I'm mapping through some metadata to get a filename and docid that is getting passed to my DocumentDownloadButton:

const DocumentsTableBody = ({ documentMetadata, tableProps }) => {
  const { Row, Data } = Table

  return (
    documentMetadata.map(doc => {
      return (
        <Row {...tableProps} key={doc.id}>
          <Data>{formatDate(doc.creationDate)}</Data>
          <Data>
            <DocumentNameWrapper>
              {doc.name}
            </DocumentNameWrapper>
          </Data>
          <DocumentDownloadButton fileName={doc.name} docId={doc.id} />
        </Row>)
    })
  )
}

From my DocumentDownloadButton I've created a function to download the file taking those two props to download onclick. The problem is it's downloading the file on refresh even before I've opened the panel which is where the click event happens

const DocumentDownloadButton = ({ docId, fileName }) => {
  const { apiFor } = useAxios()

  const downloadDocument = (id, file) => {
    apiFor('someApi')
      .get(`/documents/${id}`, { responseType: 'blob' }, {
        headers: {
          Accept: 'applicaton/octet-stream'
        } })
      .then((response) => {
        // add loading state
        const contentType = response.headers['content-type'] || 'application/octet-stream'
        const blob = new Blob([response.data], { type: contentType })
        return FileSaver.saveAs(blob, file)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  return (
    <>
      <DownloadIconContainer onClick={downloadDocument(docId, fileName)}>
        <DownloadIconSmall />
      </DownloadIconContainer>
    </>
  )
}

CodePudding user response:

That's because you're invoking the download function immediately rather than passing a reference of the function to the onClick. This should give you the intended behavior:

const DocumentDownloadButton = ({ docId, fileName }) => {
  const { apiFor } = useAxios()

  const downloadDocument = (id, file) => {
    apiFor('someApi')
      .get(`/documents/${id}`, { responseType: 'blob' }, {
        headers: {
          Accept: 'applicaton/octet-stream'
        } })
      .then((response) => {
        // add loading state
        const contentType = response.headers['content-type'] || 'application/octet-stream'
        const blob = new Blob([response.data], { type: contentType })
        return FileSaver.saveAs(blob, file)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  return (
    <>
      <DownloadIconContainer onClick={() => downloadDocument(docId, fileName)}>
        <DownloadIconSmall />
      </DownloadIconContainer>
    </>
  )
}
  • Related