0
votes

I got stuck here. I have read several solutions but still not able to figure out what is wrong. what to do?

    function sendPDFForm()
        {
          var row = SpreadsheetApp.getActiveSheet().getActiveCell().getRow();
          sendEmailWithAttachment(row);
        }
    
function sendEmailWithAttachment(row)
{
  var filename= 'Poster-CoV-WS-E1-merged.pdf';
  ...
}
    
    function getClientInfo(row)
    {
       var sheet = SpreadsheetApp.getActive().getSheetByName('test');
       if (sheet != null) {
          var values = sheet.getRange('A2:B4').getValues();
         //var values = sheet.getRange(row,1,row,3).getValues();
         var rec = values[0];
       }
      var client = 
          {
            first_name: rec[0],
            email: rec[1]
          };
      client.name = client.first_name;
      return client;
    }
    
    function sendFormToAll()
    {
       var sheet = SpreadsheetApp.getActive().getSheetByName('test');
      
       var last_row = sheet.getDataRange().getLastRow();
      
       for(var row=2; row <= last_row; row++)
       {
         sendEmailWithAttachment(row);
         sheet.getRange(row,4).setValue("email sent");
       }
    }
     

enter image description here

here I have shared the complete code. While running it it is showing error inline 54 only

1
Error is not here. It's probably somewhere else or sheet is null(Is the sheet name correct?)=>rec is undefinedTheMaster
yes sheet name is correct its test onlyvibhu sharma
Which line is line54?TheMaster
first_name: rec[0],vibhu sharma
Then sheet name is wrong. Test a another name or Show result of Logger.log(sheet)TheMaster

1 Answers

2
votes

Error explanation

You need to learn to read error messages, otherwise it will be very difficult going forward. The message states:

TypeError: Cannot read property '0' of undefined (line 54, file “Code”)

Let's parse the meaning of the message:

  1. This is a TypeError related to a primitive value undefined
  2. The running script tries to access a property named 0 from undefined
  3. The instruction that causes the error is located on line 54, file "Code.gs"

Now, "try to access" means that you instructed the script to invoke a property accessor on an object. Since the message refers to property 0, it is likely that you tried to access an element in an array by its index, which you did: rec[0].

As you got a TypeError, you expected rec to be an array, but instead the variable holds undefined. You initialized the rec variable (btw, see point 1 below) to values[0], and values to the result of calling getValues().

Because getValues always returns a two-dimensional array of values, it cannot be the problem. Then, as has been pointed out, the only other choise is that the if statement block is never reached, meaning that sheet != null is false.

The only reason why sheet != null is because getSheetByName() returns null if a sheet cannot be found. Here is a small sample reproducing the error:

function MCVE(testValue) {
  
  if(testValue != null) {
    var test = "not null";
  };
  
  test || console.log("Expected test to be defined");
}

MCVE(null);

Optimization points

  1. Never use variables out of scope. Your rec variable is declared in an if statement, but accessed outside of the statement.
  2. Keep opening { on the same line with the statement or function declaration. JavaScript assumes a lot for you, so one day you may miss the interpreter deciding to put an ; after your if statement...
  3. Do not for the love of god use I/O (input / output) operations in loops (see setValue in your for loop) - they are slow, and in Google Sheets they are very slow, use setValues() instead (and move getRange() out of the loop as well).
  4. Use strict comparison (=== / !==) unless you know what you are doing. 99% of the time using strict comparison teaches you paying attention to correctly using types and avoids frustrating bugs. For example:

const nonStrict = false == "0";
const strict = false === "0";

nonStrict && console.log("non-strict comparison evaluated to true");
strict || console.log("strict comparison evaluated to false");
false || console.log("false is falsy");
"0" && console.log("but non-empty string is truthy");