docs/_includes/api/save_attachment.html
{% include anchor.html edit="true" title="Save an attachment" hash="save_attachment" %} {% highlight "js" %} db.putAttachment(docId, attachmentId, [rev], attachment, type, [callback]); {% endhighlight %} Attaches a binary object to a document. This method will update an existing document to add the attachment, so it requires a rev if the document already exists. If the document doesn't already exist, then this method will create an empty document containing the attachment. What's the point of attachments? If you're dealing with large binary data (such as PNGs), you may incur a performance or storage penalty if you naïvely include them as base64- or hex-encoded strings inside your documents. But if you insert the binary data as an attachment, then PouchDB will attempt to store it in [the most efficient way possible]({{ site.baseurl }}/faq.html#data_types). For details, see the CouchDB documentation on attachments. #### Example Usage: {% include code/start.html id="attach1" type="callback" %} {% highlight "js" %} const attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'}); db.putAttachment('doc', 'att.txt', attachment, 'text/plain', function(err, res) { if (err) { return console.log(err); } // handle result }); {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach1" type="async" %} {% highlight "js" %} try { const attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'}); const result = await db.putAttachment('doc', 'att.txt', attachment, 'text/plain'); } catch (err) { console.log(err); } {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach1" type="promise" %} {% highlight "js" %} const attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'}); db.putAttachment('doc', 'att.txt', attachment, 'text/plain').then(function (result) { // handle result }).catch(function (err) { console.log(err); }); {% endhighlight %} {% include code/end.html %} #### Example Response: {% highlight "js" %} { "ok": true, "id": "doc", "rev": "2-068E73F5B44FEC987B51354DFC772891" } {% endhighlight %} Within Node, you must use a Buffer instead of a Blob: {% highlight "js" %} const attachment = new Buffer('Is there life on Mars?'); {% endhighlight %} For details, see the Mozilla docs on Blob or the Node docs on Buffer. If you need a shim for older browsers that don't support the Blob constructor, or you want some convenience methods for Blobs, you can use blob-util. #### Save a base64 attachment If you supply a string instead of a Blob/Buffer, then it will be assumed to be a base64-encoded string, and will be processed accordingly: {% include code/start.html id="attach3" type="callback" %} {% highlight "js" %} const attachment = "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="; db.putAttachment('doc', 'att.txt', attachment, 'text/plain', function(err, res) { if (err) { return console.log(err); } // handle result }); {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach3" type="async" %} {% highlight "js" %} try { const attachment = "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="; const result = await db.putAttachment('doc', 'att.txt', attachment, 'text/plain'); } catch (err) { console.log(err); } {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach3" type="promise" %} {% highlight "js" %} const attachment = "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="; db.putAttachment('doc', 'att.txt', attachment, 'text/plain').then(function (result) { // handle result }).catch(function (err) { console.log(err); }); {% endhighlight %} {% include code/end.html %} #### Save an inline attachment You can also inline attachments inside the document. The attachment data may be supplied as a base64-encoded string with the content_type: {% include code/start.html id="attach2" type="callback" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==" } } }; db.put(doc, function (err, result) { if (err) { return console.log(err); } // handle result }); {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach2" type="async" %} {% highlight "js" %} try { const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==" } } }; const result = await db.put(doc); } catch (err) { console.log(err); } {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach2" type="promise" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" + "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==" } } }; db.put(doc).then(function (result) { // handle result }).catch(function (err) { console.log(err); }); {% endhighlight %} {% include code/end.html %} #### Save an inline Blob/Buffer attachment You can also inline Blobs/Buffers: {% include code/start.html id="attach4" type="callback" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'}) } } }; db.put(doc, function (err, result) { if (err) { return console.log(err); } // handle result }); {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach4" type="async" %} {% highlight "js" %} try { const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'}) } } }; const result = await db.put(doc); } catch (err) { console.log(err); } {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach4" type="promise" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob(['Is there life on Mars?'], {type: 'text/plain'}) } } }; db.put(doc).then(function (result) { // handle result }).catch(function (err) { console.log(err); }); {% endhighlight %} {% include code/end.html %} #### Save many attachments at once The inline approach allows you to save multiple attachments to the same document in a single shot: {% include code/start.html id="attach5" type="callback" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob( ["And she's hooked to the silver screen"], {type: 'text/plain'}) }, "att2.txt": { "content_type": "text/plain", "data": new Blob( ["But the film is a saddening bore"], {type: 'text/plain'}) }, "att3.txt": { "content_type": "text/plain", "data": new Blob( ["For she's lived it ten times or more"], {type: 'text/plain'}) } } }; db.put(doc, function (err, result) { if (err) { return console.log(err); } // handle result }); {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach5" type="async" %} {% highlight "js" %} try { const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob( ["And she's hooked to the silver screen"], {type: 'text/plain'}) }, "att2.txt": { "content_type": "text/plain", "data": new Blob( ["But the film is a saddening bore"], {type: 'text/plain'}) }, "att3.txt": { "content_type": "text/plain", "data": new Blob( ["For she's lived it ten times or more"], {type: 'text/plain'}) } } }; const result = await db.put(doc); } catch (err) { console.log(err); } {% endhighlight %} {% include code/end.html %} {% include code/start.html id="attach5" type="promise" %} {% highlight "js" %} const doc = { "_id": "doc", "title": "Legendary Hearts", "_attachments": { "att.txt": { "content_type": "text/plain", "data": new Blob( ["And she's hooked to the silver screen"], {type: 'text/plain'}) }, "att2.txt": { "content_type": "text/plain", "data": new Blob( ["But the film is a saddening bore"], {type: 'text/plain'}) }, "att3.txt": { "content_type": "text/plain", "data": new Blob( ["For she's lived it ten times or more"], {type: 'text/plain'}) } } }; db.put(doc).then(function (result) { // handle result }).catch(function (err) { console.log(err); }); {% endhighlight %} {% include code/end.html %} See Inline Attachments on the CouchDB wiki for details.