Home > Enterprise >  Javascript for...of loop over array of objects running one too many times
Javascript for...of loop over array of objects running one too many times

Time:09-30

I have an array of objects that I'm iterating through and recording to Google Sheets, and it's working mostly fine, recording all of the objects in the array correctly. However my catch block is running at the end of the loop seemingly because it's trying to iterate over an object that doesn't exist, past the end of the array

UPDATE Even the debugger is seemingly messed up, showing a length of 6 but only 5 items in the array:

enter image description here

const objArr = [
  {sender:'soandso',count:3,lastMessageDate:'2021-09-27', lastMessageSubject: 'Test Subject'},
  {sender:'suchandsuch',count:7,lastMessageDate:'2021-08-27', lastMessageSubject: 'Test Subject 2'},
  {sender:'thisperson',count:2,lastMessageDate:'2021-03-02', lastMessageSubject: 'Test Subject 3'},
  {sender:'thatperson',count:3,lastMessageDate:'2019-09-27', lastMessageSubject: 'Test Subject 4'},
  {sender:'anotherone',count:4,lastMessageDate:'2016-02-14', lastMessageSubject: 'Test Subject 5'},
  ];
  
const keys = Object.keys(objArr[0]); 
/* Updated thanks to comments, this is what I've had in my code, I didn't reproduce it correctly */

/* Note: Counting starts at 1 for rows and columns, rather than 0 */
  
  try {
    /* each object should be recorded to a new row of the sheet, starting at row 2, 
    because row 1 is a header row */
    let row = 2;
    for(let obj of objArr) {
      /* Each property within an object should be recorded starting at 
      the leftmost column and moving to the right. Reset after each object */
      let column = 1;
      for (let key of keys) {
        console.log(key);
        activeSheet.getRange(row,column).setValue(obj[key]); //activeSheet is a Google Sheet
        console.log(obj[key]);
        column  ;
      }
      row  ;
    }
  } catch (err) {
    console.log(`${err.message} Unable to record sender information`);
  }

I end up with the following in the script logger:

...
12:00:38 PM Info    lastMessageDate
12:00:38 PM Info    2016-02-14
12:00:38 PM Info    lastMessageSubject
12:00:38 PM Info    Test Subject 5
12:00:38 PM Info    sender
12:00:38 PM Info    Cannot read property 'sender' of undefined Unable to record sender information
12:00:39 PM Notice  Execution completed

I don't understand how for...of could possibly loop more times than there are items in the array, I'm guessing maybe something to do with the i and j iterators? If someone could point out the (probably simple) mistake I made, I'd appreciate it.

CodePudding user response:

Try this:

function testBelow() {
  const objArr = [
    { sender: 'soandso', count: 3, lastMessageDate: '2021-09-27', lastMessageSubject: 'Test Subject' },
    { sender: 'suchandsuch', count: 7, lastMessageDate: '2021-08-27', lastMessageSubject: 'Test Subject 2' },
    { sender: 'thisperson', count: 2, lastMessageDate: '2021-03-02', lastMessageSubject: 'Test Subject 3' },
    { sender: 'thatperson', count: 3, lastMessageDate: '2019-09-27', lastMessageSubject: 'Test Subject 4' },
    { sender: 'anotherone', count: 4, lastMessageDate: '2016-02-14', lastMessageSubject: 'Test Subject 5' },
  ];

  let oA = objArr.map( o => [o.sender,o.count,o.lastMessageDate, o.lastMessageSubject] );
  SpreadsheetApp.getActiveSheet().getRange(1,1,oA.length,oA[0].length).setValues(oA);

}

Active Sheet:

soandso 3 2021-09-27 Test Subject
suchandsuch 7 2021-08-27 Test Subject 2
thisperson 2 2021-03-02 Test Subject 3
thatperson 3 2019-09-27 Test Subject 4
anotherone 4 2016-02-14 Test Subject 5

CodePudding user response:

It's always my own fault, I swear.

Earlier in the function, I was trying to assign the length of objArr 1 to a variable, but accidentally incremented the length value itself (which I didn't even know was possible)

Wrong: let rows = objArr.length

vs

Right let rows = objArr.length 1

  • Related