{% 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](http://pouchdb.com/faq.html#data_types).
For details, see the [CouchDB documentation on attachments](https://wiki.apache.org/couchdb/HTTP_Document_API#Attachments).
#### Example Usage:
{% include code/start.html id="attach1" type="callback" %}
{% highlight js %}
var 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 {
var attachment = new Blob(['Is there life on Mars?'], {type: 'text/plain'});
var 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 %}
var 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 %}
var attachment = new Buffer('Is there life on Mars?');
{% endhighlight %}
For details, see the [Mozilla docs on `Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or the [Node docs on `Buffer`](http://nodejs.org/api/buffer.html).
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](https://github.com/nolanlawson/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 %}
var 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 {
var attachment =
"TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
"BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==";
var 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 %}
var 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 %}
var 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 {
var doc = {
"_id": "doc",
"title": "Legendary Hearts",
"_attachments": {
"att.txt": {
"content_type": "text/plain",
"data": "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
"BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA=="
}
}
};
var 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 %}
var 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 `Blob`s/`Buffer`s:
{% include code/start.html id="attach4" type="callback" %}
{% highlight js %}
var 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 {
var doc = {
"_id": "doc",
"title": "Legendary Hearts",
"_attachments": {
"att.txt": {
"content_type": "text/plain",
"data": new Blob(['Is there life on Mars?'], {type: 'text/plain'})
}
}
};
var 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 %}
var 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 %}
var 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 {
var 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'})
}
}
};
var 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 %}
var 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](http://wiki.apache.org/couchdb/HTTP_Document_API#Inline_Attachments)
on the CouchDB wiki for details.