How to apply background color to nested list items in Google Docs using Apps Script

I want to create a script that automatically formats my study notes by adding background colors to different list levels. This would help me review my notes more efficiently without having to manually format while writing.

I’m still learning Google Apps Script and JavaScript. Here’s my current attempt:

function formatStudyNotes() {
  var document = DocumentApp.getActiveDocument();
  var content = document.getBody();
  var allListItems = content.getListItems();

  for (var i in allListItems){
    var currentItem = content.getChild(i);
    if (currentItem.Attribute.NESTING_LEVEL == 0){
      currentItem.Attribute.BACKGROUND_COLOR = "#FFFF00";
    }
  }
}

I keep getting this error: TypeError: Cannot read property "NESTING_LEVEL" from undefined.

Coming from a Python background, I suspect I might be making syntax errors. Can someone help me figure out what’s wrong with my approach?

One more thing - your for...in loop might grab prototype properties too. Add a hasOwnProperty() check or just use regular for loops with arrays in Apps Script. Also, test this with real nested lists. Sometimes this error pops up when there’s zero nesting happening.

You’re mixing up array iteration with object access. The previous answer got close but missed the real issue.

You’re looping through allListItems with for (var i in allListItems) then calling content.getChild(i) - that doesn’t work. You already have the list items.

Here’s the fix:

function formatStudyNotes() {
  var document = DocumentApp.getActiveDocument();
  var content = document.getBody();
  var allListItems = content.getListItems();

  for (var i = 0; i < allListItems.length; i++) {
    var currentItem = allListItems[i];
    if (currentItem.getNestingLevel() == 0) {
      currentItem.setBackgroundColor('#FFFF00');
    }
  }
}

Honestly though, Google Apps Script gets annoying fast. I’ve been automating document formatting for years and external tools handle this stuff way better.

Why wrestle with Apps Script every time you want to format notes? Set up automation that watches your Google Docs and applies formatting automatically. No more manual script running or debugging.

Latenode makes this easy - trigger formatting based on document changes, apply complex rules, and integrate with other study tools.

The real issue isn’t just syntax - it’s that you’re setting yourself up for constant headaches.

Sure, everyone gave you the technical fixes, but what happens when you want to update colors or add new formatting? Back to debugging Apps Script. Want this across multiple docs? Copy-paste scripts everywhere?

I’ve been there. Started with Apps Script for team documentation, spent more time fixing scripts than actually working.

External automation that watches your docs and applies formatting automatically is way smarter. No manual script running or dealing with API changes when Google updates things.

You can trigger on document changes, use different color schemes for different note types, sync formatting across all study docs. Much more flexible than hardcoded scripts.

Latenode handles Google Docs integration perfectly and lets you build complex formatting workflows without touching Apps Script again.

You’re thinking like this is Python, but it’s not. In Apps Script, you can’t chain attributes like currentItem.Attribute.NESTING_LEVEL - that property doesn’t exist on list items, so you’ll get undefined errors. Also, when you use for...in, the variable i is the actual list item, not an index number. So when you pass it to getChild(), it breaks because that method wants a numeric index. Try adding console.log(typeof i) and console.log(allListItems[i]) in your loop to see what you’re actually working with. And make sure your document has nested lists - if it’s empty or only has single-level lists, the nesting methods won’t work like you expect.

you’re using content.getChild(i) but i is the actual list item, not an index. try allListItems[i].getNestingLevel() and allListItems[i].setBackgroundColor('#FFFF00') instead. also it’s DocumentApp.Attribute.NESTING_LEVEL not just Attribute.

Your iteration method is the problem. When you use for (var i in allListItems), you get the index, but then content.getChild(i) grabs from all body children, not just list items. You need to loop through the list items directly instead.

Here’s the fixed version:

function formatStudyNotes() {
  var document = DocumentApp.getActiveDocument();
  var content = document.getBody();
  var allListItems = content.getListItems();

  for (var i = 0; i < allListItems.length; i++) {
    var currentItem = allListItems[i];
    if (currentItem.getNestingLevel() === 0) {
      currentItem.setBackgroundColor('#FFFF00');
    } else if (currentItem.getNestingLevel() === 1) {
      currentItem.setBackgroundColor('#E0E0E0');
    }
  }
}

I’ve seen this index confusion a lot in Apps Script - it’s super common when coming from other languages.

The main problem is how you’re accessing attributes and methods. Your syntax currentItem.Attribute.NESTING_LEVEL doesn’t exist in Apps Script - elements don’t have an Attribute property like that.

The other answers nailed the iteration issues, but here’s a different approach. Instead of grabbing all list items at once, try walking through the document sequentially. getListItems() sometimes misses items depending on how the doc is structured.

Try this: loop through paragraphs and check if they’re list items using getType() === DocumentApp.ElementType.LIST_ITEM. You’ll get better control over order and context.

One more thing - watch out for color formats. Some users report weird behavior mixing hex codes and RGB values in certain document states.