0

I'm getting a whole Domino Document with the

/api/data/documents/unid/

syntax. I've seen that I get a base64-encoded version of the attachment

"contentType": "application/octet-stream; name=\"Spitzbuben.docx\"",

and I'm just wondering what would be a good way to display this to the user using angular - I'm looking for some sort of file upload directive.

Do you have a suggestion?

Update:

The response to the DDS REST GET call to the document actually returns every single attachment as an multipart array; I've actually got the data in memory. I'm just wondering which would be the most elegant way of displaying to the user the fact that he can 'download' one or many of the attachments.

This is the GET call I am using right now: http://magermandemo2.ch/Development/handbuch/handbuch1_0/Handbuch_(1_0)_Dev.nsf/api/data/documents/unid/B011CE4D9E3DC16DC1257DAA00718FBB

And domino adds this (See attached file: Spitzbuben.doc) at the end of the rich-text-rendered-into-HTML:

enter image description here

Andrew Magerman
  • 1,394
  • 1
  • 13
  • 23
  • I think you don't need a file upload, because you want to display the attachment like a file download. I faced the same challenge in a XPages app, whit the data in Cloudant as base64 encoded. I have created a servlet to get my base64 code and serve it as a download. The servlet is triggered as the user wants to download the attachment. See https://github.com/flinden68/HR-Assistant/blob/master/nsf/Code/Java/ch/belsoft/hrassistant/servlet/AttachmentServlet.java – Frank van der Linden Nov 07 '16 at 17:23
  • If this is only for displaying images, you can use the ng-src directive to render it using a data uri that points to the base64 encoded data. See here: http://stackoverflow.com/questions/27637449/angularjs-img-ng-src-to-base64-data-not-url-not-working. If you want to create a link to the attachment, use ng-href and construct a URL like /dbpath/0/unid/$file/filename – Mark Leusink Nov 07 '16 at 17:52
  • Frank and Mark, many thanks for the answers - but I must have phrased my question stupidly - the GET call for the document returns all the attachments, base64 encoded, so I don't need to ask the server again for the same information. I've got the information in memory. I just want to display something like a table of files - click on the filename, the filename is downloaded (but from memory to downloads, not from server to downloads). Or is there a better way to display Rich Text with moderatly good rendition? I've solved the inline images stuff already. – Andrew Magerman Nov 07 '16 at 18:14
  • @AndrewMagerman, may be you can use the data uris, http://stackoverflow.com/questions/283956/is-there-any-way-to-specify-a-suggested-filename-when-using-data-uri – Frank van der Linden Nov 07 '16 at 20:59
  • Frank and Mark, you both helped me and I'd like to give you both the right answer – Andrew Magerman Nov 08 '16 at 13:54

2 Answers2

2

It was Frank's comment that led to the solution. RFC 2397 defines a 'data-url' method that enables you to directly put the data into the url.

Here's the HTML:

  <div class="panel panel-default" ng-if="attachments">
    <div class="panel-heading">Attachments</a></div>
    <div class="list-group">
        <a ng-repeat="attachment in attachments" class="list-group-item" download="{{attachment.filename}}"
           ng-href="{{attachment.dataurl}}">{{attachment.filename}}</a>
    </div>
</div>

And here is the section of the directive that loads the attachments (can be an array:)

   dataService.loadSingleDocumentbyUNIDMultiPart(unid).then(function (data) {
    var receiveddata = angular.fromJson(data);

if (receiveddata.Body) {
    scope.attachments = [];
    var newVal = receiveddata.Body;
    if (newVal) {

        if (mimeObj.contentDisposition) {
            //example:   "contentDisposition": "attachment; filename=\"Spitzbuben.docx\"",
            var regex = /attachment; filename=\"(.*)\"/;
            var match = regex.exec(mimeObj.contentDisposition);
            if (match) {
                // example:  "contentType": "application/octet-stream; name=\"Spitzbuben.docx\"",
                var mediatype = mimeObj.contentType.substring(0, mimeObj.contentType.indexOf(";"));

                // https://www.rfc-editor.org/rfc/rfc2397 dataURL definition
                var thisAttachment = {
                    "filename": match[1],
                    "dataurl": "data:" + mediatype + ";base64" + "," + mimeObj.data
                };
                scope.attachments.push(thisAttachment);
            }
        }
    }
} else {
    // the body has not been received so we clean stuff u
    scope.attachments = null;
}

You'll also need to explicitly say that these data urls are OK and safe with the following .config setting:

$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|data):/);
Community
  • 1
  • 1
Andrew Magerman
  • 1,394
  • 1
  • 13
  • 23
0

One simple way to download any file from the server, regardless of angular or anything else is to have the URL in the anchor tag.

<a target="_self" href="example.com/uploads/Spitzbuben.docx" download="Spitzbuben.docx">

Not sure about your authorization stuff. Hope this helps

RL89
  • 1,866
  • 5
  • 22
  • 39