diff --git a/backend/controllers/transactionController.js b/backend/controllers/transactionController.js index ad25dcb..d811b9a 100644 --- a/backend/controllers/transactionController.js +++ b/backend/controllers/transactionController.js @@ -342,7 +342,8 @@ const deleteCategory = async (req, res) => { const exportTransactions = async (req, res) => { try { - const transactions = await IncomeExpense.find({ user: req.user._id, isDeleted: false }).lean(); + const userId = req.user._id || req.user.id; + const transactions = await IncomeExpense.find({ user: userId, isDeleted: false }).lean(); const csvData = transactions.map(({ _id, user, name, category, cost, addedOn, isIncome }) => ({ id: _id, @@ -354,8 +355,11 @@ const exportTransactions = async (req, res) => { isIncome, })); - // Use Papa.unparse directly - const csv = Papa.unparse(csvData, { header: true }); + // Use Papa.unparse directly with explicit columns for reliability even on empty datasets + const csv = Papa.unparse(csvData, { + header: true, + columns: ['id', 'user', 'name', 'category', 'cost', 'addedOn', 'isIncome'], + }); res.setHeader('Content-Type', 'text/csv'); res.setHeader('Content-Disposition', 'attachment; filename="paisable_transactions.csv"'); diff --git a/frontend/src/utils/transactions.js b/frontend/src/utils/transactions.js index 37c115e..93ba2f0 100644 --- a/frontend/src/utils/transactions.js +++ b/frontend/src/utils/transactions.js @@ -9,7 +9,8 @@ export const handleExportCSV = async () => { const res = await api.get('/transactions/export', { responseType: 'blob', // Important for file download }); - const blob = new Blob([res.data], { type: 'text/csv' }); + const blobData = res.data instanceof Blob ? res.data : new Blob([res.data], { type: 'text/csv;charset=utf-8;' }); + const blob = new Blob([blobData], { type: 'text/csv;charset=utf-8;' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url;