From c6c3876e861245c2a31e3c5eba3b5048bb690f8c Mon Sep 17 00:00:00 2001
From: Jay L <monkeydzeke@protonmail.com>
Date: Tue, 9 Oct 2018 01:34:28 -0700
Subject: [PATCH] Fixes unparsing using 'skipEmptyLines' = 'greedy' when using
 headers (#569)

---
 papaparse.js        | 23 +++++++++++++++++++----
 tests/test-cases.js | 18 ++++++++++++++++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/papaparse.js b/papaparse.js
index 94c81b6..6a0a115 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -403,19 +403,34 @@ if (!Array.isArray)
 			for (var row = 0; row < data.length; row++)
 			{
 				var maxCol = hasHeader ? fields.length : data[row].length;
-				var r = hasHeader ? fields : data[row];
 
-				if (skipEmptyLines !== 'greedy' || r.join('').trim() !== '')
+				var emptyLine = false;
+				var nullLine = hasHeader ? Object.keys(data[row]).length === 0 : data[row].length === 0;
+				if (skipEmptyLines && !hasHeader)
+				{
+					emptyLine = skipEmptyLines === 'greedy' ? data[row].join('').trim() === '' : data[row].length === 1 && data[row][0].length === 0;
+				}
+				if (skipEmptyLines === 'greedy' && hasHeader) {
+					var line = [];
+					for (var c = 0; c < maxCol; c++) {
+						var cx = dataKeyedByField ? fields[c] : c;
+						line.push(data[row][cx]);
+					}
+					emptyLine = line.join('').trim() === '';
+				}
+				if (!emptyLine)
 				{
 					for (var col = 0; col < maxCol; col++)
 					{
-						if (col > 0)
+						if (col > 0 && !nullLine)
 							csv += _delimiter;
 						var colIdx = hasHeader && dataKeyedByField ? fields[col] : col;
 						csv += safe(data[row][colIdx], col);
 					}
-					if (row < data.length - 1 && (!skipEmptyLines || maxCol > 0))
+					if (row < data.length - 1 && (!skipEmptyLines || (maxCol > 0 && !nullLine)))
+					{
 						csv += _newline;
+					}
 				}
 			}
 			return csv;
diff --git a/tests/test-cases.js b/tests/test-cases.js
index deb2e65..98509de 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1654,6 +1654,24 @@ var UNPARSE_TESTS = [
 		input: [[null, ' '], [], ['1', '2']],
 		config: {skipEmptyLines: 'greedy'},
 		expected: '1,2'
+	},
+	{
+		description: "Returns empty rows when empty rows are passed and skipEmptyLines is false with headers",
+		input: [{a: null, b: ' '}, {}, {a: '1', b: '2'}],
+		config: {skipEmptyLines: false, header: true},
+		expected: 'a,b\r\n," "\r\n\r\n1,2'
+	},
+	{
+		description: "Returns without empty rows when skipEmptyLines is true with headers",
+		input: [{a: null, b: ' '}, {}, {a: '1', b: '2'}],
+		config: {skipEmptyLines: true, header: true},
+		expected: 'a,b\r\n," "\r\n1,2'
+	},
+	{
+		description: "Returns without rows with no content when skipEmptyLines is 'greedy' with headers",
+		input: [{a: null, b: ' '}, {}, {a: '1', b: '2'}],
+		config: {skipEmptyLines: 'greedy', header: true},
+		expected: 'a,b\r\n1,2'
 	}
 ];