Fixing CSV Line Appending Issue in SuiteScript 2.x

You are encountering the following error in SuiteScript 2.x:

TypeError: Cannot find function endsWith in object ...

This error occurs when you’re attempting to append data to a CSV file using file.getContents() and then trying to check if it ends with a newline (n) using .endsWith(). In SuiteScript 2.x, this function may not be available for the object returned by getContents(). Additionally, if the file doesn’t end with a newline, appending a new row could cause the new row to be added as a column instead of a new line.

Root Cause:

  • The file.getContents() method returns the entire content of the file, which is expected to be a string.
  • If the file is malformed, or if the last row in the file doesn’t end with a newline, the new data might be appended incorrectly (as part of the last row instead of a new row).
  • The error arises from trying to use endsWith() on an object that doesn’t support this method, likely because getContents() is returning something other than a string (or the string is malformed).

Solution:

To handle this issue and ensure that rows are appended correctly to the CSV file, follow these steps:

  1. Load the File:
  2. Use file.load() to load the file from the file cabinet.
  3. Ensure String Content:
  4. Convert the result from getContents() into a string. This ensures that subsequent operations treat the file content as a valid string.
  5. Check for Newline at End of File:
  6. Use slice(-1) to check whether the content ends with a newline (n). This is a simple and safe method supported in SuiteScript 2.x.
  7. Append New Row Safely:
  8. If the content doesn’t end with a newline, prepend a newline before appending the new row.

Implementation Example:

Here’s how you can fix this issue and safely append rows to a CSV file:

/**
 * Safely appends a new row to the given CSV file object.
 * 
 * @param {Object} fileObj - The file object representing the CSV file.
 * @param {Array} rowValues - An array of values for the new row.
 */
function appendCsvRowSafely(fileObj, rowValues) {
    // Ensure the file contents are a string
    var content = String(fileObj.getContents());
    
    // Check if the last character is a newline
    var endsWithNewline = content.slice(-1) === 'n';
    
    // Convert the row values to a comma-separated string
    var row = rowValues.join(',');
    
    // If the content doesn't end with a newline, add one before appending
    if (!endsWithNewline) {
        row = 'n' + row;
    }
    
    // Append the row and save the file
    fileObj.appendLine({ value: row });
    fileObj.save();
}

Usage Example:

Here’s how you can use this function in the context of your CSV handling logic:

// Load the existing file
var existingFile = file.load({ id: fileId });

// Prepare the data for the new row
var newRow = [
    'NewItem',
    'New Description',
    'Strand Count',
    'Class',
    'Component #1',
    'Qty'
];

// Append the new row safely
appendCsvRowSafely(existingFile, newRow);

This ensures that if the CSV file does not end with a newline, it will be correctly formatted by prepending one before appending the new row. This will prevent the new data from being appended as part of the last column.

Best Practices:

  • Always verify that getContents() returns a valid string before performing string operations.
  • Use slice(-1) instead of .endsWith() for better compatibility with SuiteScript 2.x.
  • Ensure that each row in your CSV ends with a newline to maintain proper formatting when adding new data.

Additional Notes:

  • This approach works seamlessly for CSV files, where each row is represented by a single line of comma-separated values.
  • If you are appending multiple rows at once, ensure that you’re consistently applying the newline handling logic for each row.

Leave a comment

Your email address will not be published. Required fields are marked *