user image

nico
Published in : 2022-03-11

Axios download CSV from web api returns error : TypeError: Cannot read properties of null (reading '1')

Javascript

Hello all I use the following code to make axios make download the file csv:

I have in response.data

data: "Date;Provider;BookingNumber;PNR;Action;PCC;CountryID;Savings;OriginalFare;NewFare;BONewFare;PerCentageDifference;IsPublicOrNetFare;AcctCorpCode;OPcc;PlatingCarrier;RebookedCarrier;Routes;Queue;Online_Offline;LastPurchase;MaxRebook\r\n2022-01-01 01:16:19;Galileo;;0T9FKX;optimization;;;60.00;458.69;398.69;398.69;0;False;;36PR;HC;;;60;False;1/1/2022 1:16:19 AM;\r\n2022-01-05 16:31:24;Galileo;;0TXVHJ;optimization;;;50.00;821.67;771.67;771.67;0;False;;36PR;HC;;;60;False;1/5/2022 4:31:24 PM;\r\n2022-01-11 12:38:18;Galileo;;0VRRH4;optimization;;;18.00;246.40;228.40;228.40;0;False;;36PR;TU;;;60;False;1/11/2022 12:38:18 PM;\r\n2022-01-12 12:51:51;Galileo;;0VYC6S;optimization;;;44.00;549.14;505.14;505.14;0;False;;36PR;ET;;;60;False;1/12/2022 12:51:51 PM;\r\n2022-01-13 12:25:38;Galileo;;0W3CXR;optimization;;;106.00;722.75;616.75;616.75;0;False;;36PR;TK;;;60;False;1/13/2022 12:25:38 PM;\r\n2022-01-14 20:19:16;Galileo;;0WB0RG;optimization;;;18.00;226.37;208.37;208.37;0;False;;36PR;TU;;;60;False;1/14/2022 8:19:16 PM;\r\n2022-01-19 19:47:47;Galileo;;0X25Q2;optimization;;;30.00;280.40;250.40;125.20;50,0;False;;36PR;TU;;;60;False;1/19/2022 7:47:47 PM;\r\n2022-01-24 13:20:31;Galileo;;0XRVDR;optimization;;;228.00;1767.09;1539.09;513.03;66,666666666666666666666666670;False;;36PR;HF;;;60;False;1/24/2022 1:20:31 PM;\r\n"

   axios.post(url, obj)
            .then(response => {


               
                var blob = new Blob(
                    [response.data], // Blob parts.
                    {
                        type: "text/csv;charset=utf-8"
                    }
                );

           

                const url = window.URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;

                var contentDisposition = response.headers["content-disposition"];
                var match = contentDisposition.match(/filename\s*=\s*"(.+)"/i);
                var filename = match[1];

                link.setAttribute('download', filename); //or any other extension
                document.body.appendChild(link);
                link.click();
                document.body.appendChild(link);
            })
            .catch(error => {
                dispatch(errorData());
                alert(error);
                //TODO: handle the error when implemented
            })
    }

Can you tell me what is going on?

Thanks

Comments

Mohamed Atef Date : 2022-03-11

Best answers

46

Best answers

46

Can you please add console.log after creating the blob then console.log to get the value of the URL, I belive that the error is coming from these 3 lines 

var contentDisposition = response.headers["content-disposition"];
var match = contentDisposition.match(/filename\s*=\s*"(.+)"/i);
var filename = match[1]; 

also I can share an example i did before to get download the CSV

let res1 = await axios.get(BackendURL+'/api/files/download/'+this.state.currentDocument?.documentId, conf);
let blob = new Blob([res1.data], {type: 'application/pdf'});
const fileURL = window.URL.createObjectURL(blob);
this.setState({ currentDocumentURL: fileURL });

please note that type is ‘application/pdf’ i need to change it if I will display the response but to get the URL you can use any type

nico Date : 2022-03-11

Best answers

4

Best answers

4

Hello Mohamed It was a problem of regular expression,

what is the best way of getting the filename from the content-disposition ?

Moreover as to avoid reinventing the code to make the file downloading automatic: I use the js-file-download npm:

https://www.npmjs.com/package/js-file-download


 

 

import fileDownload from 'js-file-download';

  axios.post(url, obj)
            .then(response => {

                fileDownload(response.data, 'report.csv')
            })
            .catch(error => {
                dispatch(errorData());
                alert(error);
                //TODO: handle the error when implemented
            })

Mohamed Atef Date : 2022-03-11

I don't think you need to use "content-disposition", why you need to use it 

nico Date : 2022-03-11

Best answers

4

Best answers

4

Because the file name is generated by the backend so the js client needs to read it from content-disposition header.

For example: 

Report-20220311.csv 

The server generate the name with the date and sends in the content-disposition header

 

  return new FileContentResult(result,"text/csv")
               {
                   FileDownloadName = $"Report{DateTime.Now.ToString("YYYYmmdd")}.csv"
               };

Mohamed Atef Date : 2022-03-11

You can set different names to the files from the frontend when the user download it 

Leave a comment

Join us

Join our community and get the chance to solve your code issues & share your opinion with us

Sign up Now

Related posts

Javascript Add (+) issue
Publish date: 2022-02-26 | Comments: 1

Tag: Javascript

Check if div have touch another div
Publish date: 2022-03-02 | Comments: 1

Tag: Javascript

JavaScript variable for Changing CSS Height
Publish date: 2022-02-12 | Comments: 1

Tag: Javascript

How to get audio input and audio output as one stream?
Publish date: 2022-02-13 | Comments: 1

Tag: Javascript

jquery undefined function
Publish date: 2022-02-28 | Comments: 1

Tag: Javascript

Coping plain text into form bug.
Publish date: 2022-02-11 | Comments: 1

Tag: Javascript

Vanilla JavaScript Next & prev Navigation
Publish date: 2022-02-22 | Comments: 1

Tag: Javascript

Can we add a javascript or jQuery to the URL?
Publish date: 2022-03-05 | Comments: 2

Tag: Javascript