title: Google App Script: TypeError: Cannot read property 'length' of undefined (line *, file "Code")
body: <h4>The Goal</h4>
  <p>Prevent the script from copying blank (empty) rows from source to destination which is causing the error.</p>
  <hr />
  <h4>Error Details:</h4>
  <blockquote>
  <p>Google App Script: TypeError: Cannot read property 'length' of undefined (line *, file &quot;Code&quot;)</p>
  </blockquote>
  <p>This error, refers to the line:
  <code>dstSheet.getRange(dstLastRow + 1, 1, values.length, values[0].length).setValues(values);</code></p>
  <hr />
  <h4>The full code</h4>
  <p>I am using the following code from <a href="https://stackoverflow.com/a/70690191/13255292">HERE</a> which has been slightly modified. The error occurs with and without the modification. The logic of the code is: If destination sheet does not contain ID, import ID, and specific columns from source to destination.</p>
  <pre><code>function importNewEmployeeIds() {
    const srcSheetName = 'Source';
    const dstSheetName = 'Destination';
    const srcSheet = SpreadsheetApp.openById(&quot;SpreadsheetID1&quot;).getSheetByName(srcSheetName);
  
    const dstSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dstSheetName);
  
    // Retrieve values from source sheet.
    var headerRowNumber = 1;
    const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
  
    // Retrieve values from destination sheet and create an object for searching the ID.
    const dstLastRow = dstSheet.getLastRow();
    const dstObj = dstLastRow == 0 ? {} : dstSheet.getRange(&quot;A1:A&quot; + dstLastRow).getValues().reduce((o, [a]) =&gt; (o[a] = true, o), {});
  
    // Create an array for putting to the destination sheet.
    const values = srcValues.filter(r =&gt; !dstObj[r[1]]).map(r =&gt; [r[1], r[19], &quot;&quot;, r[18]]);
  
    // Put the values to the destination sheet.
    dstSheet.getRange(dstLastRow + 1, 1, values.length, values[0].length).setValues(values);
  }
  </code></pre>
  <h4>Troubleshooting</h4>
  <p>[Source] <em>Before</em> script is run.</p>
  <pre><code>|  A   |B|  C   |  D   |
  |200001| |Email2|Email1|
  |200001| |Email2|Email1|
  |200006| |Email4|Email3|
  |200007| |Email6|Email5|
  |      | |      |      |
  </code></pre>
  <p>[Destination] <em>Before</em> script is run.</p>
  <pre><code>|  A   |B|  C   |  D   |
  |200001| |Email2|Email1|
  </code></pre>
  <p>[Destination] <em>After</em> script is run.</p>
  <pre><code>|  A   |B|  C   |  D   |
  |200001| |Email2|Email1|
  |200006| |Email4|Email3|
  |200007| |Email6|Email5|
  |      | |      |      | &lt;-- Notice the blank row. I don't want the blank row.
  </code></pre>
  <p>Once the script runs, it copies row data from source to destination. The problem is, the script will also copy the blank (empty) rows to the source sheet.</p>
  <p>[Destination] <em>Expected Results</em> - No blank rows</p>
  <pre><code>|  A   |B|  C   |  D   |
  |200001| |Email2|Email1|
  |200006| |Email4|Email3|
  |200007| |Email6|Email5|
  </code></pre>
  <hr />
  <h4>Rookie Solutions that I can think of:</h4>
  <p><strong>Option A)</strong> At the beginning of the script, I could first delete all empty rows from the destination. This is less efficient, and does not fix the root of the issue, but at least it fixes my problem.</p>
  <pre><code>function removeEmptyRows(){
    var sh = SpreadsheetApp.getActiveSheet();
    var maxRows = sh.getMaxRows(); 
    var lastRow = sh.getLastRow();
    if (maxRows-lastRow != 0){
      sh.deleteRows(lastRow+1, maxRows-lastRow);
      }
  }
  </code></pre>
  <p>Code found: <a href="https://stackoverflow.com/a/26387265/13255292">HERE</a></p>
  <hr />
  <p><strong>Option B)</strong> Update the original code so it does not copy the blank rows.</p>
  <p>[BEFORE]</p>
  <pre><code>  const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
  </code></pre>
  <p>[AFTER]</p>
  <pre><code>  const srcValuesAndBlankRows = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
    const srcValues = srcValuesAndBlankRows.filter(String); //Removes Blank Rows
  </code></pre>
  <p>Code Found: <a href="http://stackoverflow.com/a/56856343/13255292">HERE</a></p>