The Files service handles file uploads, downloads, and deletion. It’s useful for managing user-uploaded content, documents, images, and other binary data.
Overview
import { SnackBaseClient } from "@snackbase/sdk";
const client = new SnackBaseClient({
baseUrl: "https://api.example.com",
});
// Access the files service
const files = client.files;
Upload Files
Upload a file from a browser or React Native environment:
// From a file input
const fileInput = document.querySelector("#file-input");
const file = fileInput.files[0];
const metadata = await client.files.upload(file);
// Returns: { path: string, filename: string, size: number, content_type: string, ... }
Upload with custom options:
const metadata = await client.files.upload(file, {
filename: "custom-name.pdf",
contentType: "application/pdf"
});
Upload a Blob directly:
const blob = new Blob(["Hello, world!"], { type: "text/plain" });
const metadata = await client.files.upload(blob, {
filename: "hello.txt"
});
Download Files
Get a download URL for a file:
const url = client.files.getDownloadUrl("/uploads/documents/report.pdf");
// Use in an <img> tag
const img = document.createElement("img");
img.src = url;
// Or open in new tab
window.open(url, "_blank");
// Or use with fetch
const response = await fetch(url);
const blob = await response.blob();
Download URLs include authentication tokens and are temporary. Don’t cache them
for extended periods.
Delete Files
Delete a file from the server:
await client.files.delete("/uploads/documents/old-report.pdf");
Complete Example
File upload component with progress:
import { useState } from "react";
import { SnackBaseClient } from "@snackbase/sdk";
const client = new SnackBaseClient({
baseUrl: "https://api.example.com"
});
function FileUpload() {
const [uploading, setUploading] = useState(false);
const [uploadedFile, setUploadedFile] = useState(null);
const handleFileChange = async (event) => {
const file = event.target.files[0];
if (!file) return;
setUploading(true);
try {
const metadata = await client.files.upload(file);
setUploadedFile(metadata);
} catch (error) {
console.error("Upload failed:", error);
} finally {
setUploading(false);
}
};
const handleDelete = async () => {
if (uploadedFile) {
await client.files.delete(uploadedFile.path);
setUploadedFile(null);
}
};
return (
<div>
<input
type="file"
onChange={handleFileChange}
disabled={uploading}
/>
{uploading && <p>Uploading...</p>}
{uploadedFile && (
<div>
<p>Uploaded: {uploadedFile.filename}</p>
<p>Size: {uploadedFile.size} bytes</p>
<a href={client.files.getDownloadUrl(uploadedFile.path)}>
Download
</a>
<button onClick={handleDelete}>Delete</button>
</div>
)}
</div>
);
}
Integration with Records
Store file metadata in records:
// 1. Upload the file
const metadata = await client.files.upload(file);
// 2. Create a record with the file reference
const record = await client.records.create("documents", {
title: "My Document",
file_path: metadata.path,
file_name: metadata.filename,
file_size: metadata.size,
uploaded_at: new Date().toISOString()
});
Retrieve and display files from records:
// Get records with files
const documents = await client.records.list("documents");
// Display each document
documents.items.forEach(doc => {
const url = client.files.getDownloadUrl(doc.file_path);
console.log(`${doc.title}: ${url}`);
});
Error Handling
Handle file upload errors:
try {
const metadata = await client.files.upload(file);
} catch (error) {
if (error instanceof ValidationError) {
console.error("Invalid file:", error.fields);
} else if (error instanceof PayloadTooLargeError) {
console.error("File too large");
} else {
console.error("Upload failed:", error.message);
}
}
Next Steps