Click Button And File Sent, i.e. Browser Downloading?

Click Button And File Sent, i.e. Browser Downloading? Basically doing what NR does when you export a flow... you just select export, set the options for the resulting file, and then the file is downloaded. It is this last step in the process I want to mimic via dashboard button click.

Looking at the documentation I found the following... but the following example requires a get to initiate the download... not a button click.

https://flows.nodered.org/flow/db68bd4934cf46f39e6e453a348bc419

Any suggestion how to do this? I don't want the operator to do anything but click said button, the file name, and path will be already known at the point of button click.

You fake it.

In a template you add an anchor with button styling. The href of the anchor points to the endpoint.

<a class="button" href="../endpointname">Download</a>

The flow becomes:
Http-in (get /endpointname)-> file read -> http-response

To the end user, it looks, feels & smells exactly like a button.

If for some mad reason you need to use a button, you will need client side scripting to do a get request.

Is that (basically) how NR does it to download an exported flow?

OK... So this works with a few issues...

[{"id":"98261154.3006","type":"http response","z":"b749c94d0e4ba00b","name":"","statusCode":"","headers":{},"x":510,"y":100,"wires":[]},{"id":"34dc99e5.495466","type":"file in","z":"b749c94d0e4ba00b","name":"","filename":"/tmp/test.dmp","filenameType":"str","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":340,"y":80,"wires":[["98261154.3006"]]},{"id":"38d65d59.1d8aa2","type":"catch","z":"b749c94d0e4ba00b","name":"Download","scope":null,"uncaught":false,"x":100,"y":140,"wires":[["5b18a8e7.fb8da8"]]},{"id":"5b18a8e7.fb8da8","type":"debug","z":"b749c94d0e4ba00b","name":"Message","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":240,"y":140,"wires":[]},{"id":"67ecfa7f.3f0e24","type":"http in","z":"b749c94d0e4ba00b","name":"","url":"/tmp/test.dmp","method":"get","upload":false,"swaggerDoc":"","x":130,"y":100,"wires":[["34dc99e5.495466"]]},{"id":"a8c2985e.d23ad8","type":"ui_template","z":"b749c94d0e4ba00b","group":"dfb4a60f.d788f8","name":"Download","order":0,"width":0,"height":0,"format":"<div >\n    <a class=\"button\" href=\"/tmp/test.dmp\">Test</a>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":100,"y":60,"wires":[[]]},{"id":"dfb4a60f.d788f8","type":"ui_group","name":"Data Export","tab":"48418b79.0f5834","order":1,"disp":true,"width":"12"},{"id":"48418b79.0f5834","type":"ui_tab","name":"Dashboard","icon":"dashboard","order":1}]

Question... How do I get a 'known' file type to download, say a txt file, and not have the browser try to handle it, for example, a txt (text file) the browser will likely try to open the text file if setup to do so... I always want the file to go to an actual file. I want to say you have the change the MINE type?

Question... for some reason, even with a set the class type, I get a link not a button? I happen to be using Firefox, but I can't see that is being material to the class not being honored?

You need to add a Content-Disposition header to tell the browser it's an attachment.

E.g. Content-Disposition: attachment; filename=data.txt

As for your styling, there are several ways. Here is a good thread: css - How to make an HTML anchor tag (or link) look like a button? - Stack Overflow

Ah! Attachment... OK. But I see one more thing tripping me up. The file created will vary by file name. Depending on what the operator does, the file may be named 'a.txt' or 'b.txt' etc. When I first asked the question I was thinking I just would name the button 'Download' and it would trigger the applicable action. I figured I could just pass the file name along.

However, given it seems the only way to do this, is to use the http end-point node, a template node and then a http response node, to get the button effect. How do I adjust or change the template node to reflect different file name?

Or... Can I trigger the download without even a button? Thinking it might just be easier since I know the path and file name (which will be on the NR file system say /tmp/a.txt or /tmp/b.txt, and I just pass that reference along and the download happens as the last step in the flow that actually creates the file?

I realize I am changing the question in mid stream, sorry about that, but clearly it can be done... NR when you do an export, is a dynamic process, it gets the flow content (say formatted as JSON), sets the file name to flows.json , and triggers a download of said flow as now a file which clearly it creates for the download. Just thinking I can just drop the requirement of using any type of UI element, and just create the file and trigger the download.

But with what I have working now I don't see being able to adapt that as needed, dynamically changing the link reference so the UI element reflects the right link, or how to bypass the entire UI element.

You can set headers dynamically by setting msg.headers. In the flow in this thread, there is a function "Set Headers" - see that for an example.

Sorry I don't have the time to read the rest of your post, hopefully someone else will chime in.

@Steve-Mcl,

No worries... You helped me a great deal. Thanks.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.