I’ve been struggling with this for a while now.
I have a smart action which purpose is to download a pre-filled odt file:
{
name: 'Générer un courrier',
type: 'single',
download: true,
}
In my route, it look like this :
router.post('/actions/generer-un-courrier', permissionMiddlewareCreator.smartAction(), (request, response) => {
const contract_id = request.body.data.attributes.ids[0];
const body = {
letter: {
contract_id,
letter_model_id: 1
}
};
axios.post(`${API_URL}/forest_admin/letters`, body, {
headers: {
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`,
'X-CURRENT-USER-EMAIL': request.user.email,
}
}).then(res => {
// response.setHeader('Content-Type', 'application/vnd.oasis.opendocument.text');
// response.setHeader('Transfer-Encoding', 'chunked');
// // response.setHeader('Connection', 'keep-alive');
// response.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
// response.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
// response.setHeader('Content-Disposition', 'attachment; filename="blank_letter_so.odt"');
// response.setHeader('Content-Transfer-Encoding', 'binary');
// response.set({ ...res.headers });
response.send(res.data);
}).catch(err => {
response.status(400).send({ error: err.response.data.error.message });
});
});
My API provider is sending me a binary odt file which I’d like to send back to Forest Admin.
I have tried basically all combinations of headers settings before send()
(all the comments above). At the very best, I receive a corrupted unreadable file. I’ve been trying to copy the response headers as well : response.set({ ...res.headers });
I’m clearly missing something here, all I want to do is transfer my binary file to my FA front-end.
Note that everything is working fine in Postman.
Hello @JeremyV ,
Just to be sure, do you need your Axios call to be a POST
and not a GET
?
I tried to create a simple file server locally (with the http-server
nom package), and if I change axios.post
to axios.get
in you code sample (and adapt the file URL of course) I can receive a file via my Forest Admin panel.
If changing the post
to get
is not right, could you tell me what api provider your are using? If they provide a free account I could try to reproduce you issue.
Thank you
Hello @anon79585656
Indeed this is a POST and not a GET :
It might be quite difficult to allow you to test this API since this is in a private domain accessible through VPN… I’ll see what I can do.
Hey @JeremyV ,
We have the following example with some static file.
https://docs.forestadmin.com/documentation/reference-guide/actions/create-and-manage-smart-actions#downloading-a-file
But, we don’t have any example with your use case. I’ll try to reproduce your issue.
Best regards,
Morgan
More informations
This is an exemple of the file we are supposed to download :
blank_letter_so.tar (15.5 KB)
This is what we get in FA :
blank_letter_so.tar (40 KB)
(files have been manually archived to be uploaded here)
vince
May 6, 2021, 8:11am
6
Hey @JeremyV , I’ll try to reproduce
vince
May 6, 2021, 9:27am
7
I just tried and I had no issue. I have the following code:
async function downloadFromGet(request, response) {
const requestResponse = await superagent.post(`${process.env.API_URL}/download-odt`);
response.setHeader('content-type', 'application/vnd.oasis.opendocument.text');
response.setHeader('content-disposition', 'attachment; filename="blank_letter_so.odt"');
response.setHeader('accept-ranges', 'bytes');
response.send(requestResponse.body);
}
1 Like
Hi @morganperre @vince
Sorry I had to put this subject on the side for a few weeks.
I managed to get an access for you to test from the real API.
Can you provide an email address where I can share the Postman collection.
Thank you.
vince
June 2, 2021, 7:35am
9
Hey @JeremyV ,
As I say it works on our side so it must be coming from your code . Did you try the code above ?
Yes I did. no difference unfortunately.
Here it is:
router.post('/actions/generer-un-courrier', permissionMiddlewareCreator.smartAction(), async (request, response) => {
const contract_id = request.body.data.attributes.ids[0];
const body = {
letter: {
contract_id,
letter_model_id: 1
};
const requestResponse = await axios.post(`${API_URL}/forest_admin/letters`, body, {
headers: {
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`,
'X-CURRENT-USER-EMAIL': request.user.email,
}
});
response.setHeader('Content-Type', 'application/vnd.oasis.opendocument.text');
response.setHeader('Content-Disposition', 'attachment; filename="blank_letter_so.odt"');
response.setHeader('accept-ranges', 'bytes');
response.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
response.send(requestResponse.data);
});
i’ve got no other options…
vince
June 3, 2021, 7:00am
11
Weird. Could you try with superagent
instead of axios
?
If that’s still not that this mean the issue come from your url not returning the right format/data
The initial script is still not working. In the mean time I had another case which is basically the same phenomenon.
router.post('/actions/courrier-changement-de-syndic-aux-fournisseurs', permissionMiddlewareCreator.smartAction(), (request, response) => {
const maintenance_contract_ids = request.body.data.attributes.ids;
models.maintenanceContracts.findOne({
where: { id: maintenance_contract_ids[0] }
}).then(maintenanceContract => {
const place_id = maintenanceContract.placeIdKey;
const body = {
place_id,
maintenance_contract_ids
};
axios.post(`${API_URL}/forest_admin/maintenance_contracts/send_new_management_info`, body, {
headers: {
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`,
'X-CURRENT-USER-EMAIL': request.user.email,
}
}).then(res => {
response.setHeader('Content-Type', 'application/zip');
response.setHeader('Content-Disposition', 'attachment; filename="Information de changement de syndic.zip"');
response.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
response.send(res.data);
});
});
});
In Postman, the zip file I get is 58 kB. In FA, the file I download is 107kB, and is corrupted.
Guys, just to let you know : it’s WORKING with superagent
.
Don’t ask me why or how.
1 Like