Power-up development: does .initialize run before cards are fully loaded?

I am creating my first power-up for Trello, and I’ve run into a bit of a roadblock. The purpose of the power-up is very simple - to expose the state of all checklists on the back of a card in the form of a progress bar on the front of the card (using card-badges).

It very almost works, but not quite… When I load the board, all cards show the string “N/A”, which is the fallback string when no checklist items are detected. The cards obviously have checklists though, as the in-built checklist card-badge works just fine, showing (3/7, or 2/14, or whatever the case may be). However, the moment I check or uncheck any item in a checklist, the progress bar appears on the front as expected.

My guess is that the .initialize method is being called before the cards are fully loaded, or something along those lines. As a first-timer here, I expect I am probably just missing something extremely obvious… Can anyone point me in the right direction?

The code looks like this:

<!DOCTYPE html>
<html>
<head>
<title>Checklist Progress Power-Up</title>
<script src="https://p.trellocdn.com/power-up.min.js"></script>
</head>
<body>
<script>

function calculateChecklistProgress(card) {
let totalItems = 0;
let completedItems = 0;
if (card.checklists) {
card.checklists.forEach(function(checklist) {
if (checklist.checkItems) {
totalItems += checklist.checkItems.length;
completedItems += checklist.checkItems.filter(function(item) {
return item.state === 'complete';
}).length;
}
});
}

if (totalItems === 0) {
return 'N/A';
}

const progressPercentage = ((completedItems / totalItems) * 100).toFixed();

const progressBar = createProgressBar(progressPercentage);

return progressBar;
}

function createProgressBar(progressPercentage) {
const barLength = 10;
const completedChars = Math.round((progressPercentage / 100) * barLength);
const remainingChars = barLength - completedChars;

const progressBar = ' █ '.repeat(completedChars) + ' __ '.repeat(remainingChars)

return ` ${progressBar} ${progressPercentage}%`;
}

function updateCardBadges(t) {
return t.card('all')
.then(function(card) {
window.card = card;
const progress = calculateChecklistProgress(card);
return [{
text: progress,
color: 'light-gray',
}];
});
}

window.TrelloPowerUp.initialize({
'card-badges': function(t, options) {
return t.card('all')
.then(function(card) {
window.card = card;
return updateCardBadges(t);
});
},
});
</script>
</body>
</html>

I’ve delved a bit deeper now, and discovered that the actual breaking point is where I try to access “checklist.checkItems.length” for the first time. I’m finding that until the state of a checklist item changes at least once, I get this error:

“TypeError: Cannot read properties of undefined (reading ‘length’)”

The moment I change the state of any checklist item though, the property becomes “defined”, and thus, “readable”. Does anyone know how I could define/read it from the get go? Is there perhaps another way to access checklist properties I just don’t know about?

It appears there is an issue with the Trello Power-Up ‘card-badges’ t.card() reference. I can get to the checkListItems on the BACK of the card, but not from the badge.

Trello posted here and stated that it should return an array of checkItems, per this post:

Here is a sample I used to update my Trello Type-Definitions file:

/// <reference path="trello.d.js" />
window.TrelloPowerUp.initialize({ 
  'card-badges': 
    /**
     * Returns the card badge
     * @param {TrelloObject} t 
     * @returns {TrelloCardBadgesOption[]}
     */
    async (t) =>{
    /** @type {TrelloCard} */
    const card = await t.card("id", "checklists");
    /** @type {TrelloChecklist[]} */
    const checklists = card.checklists;
    const totalItemCount = checklists.reduce((acc, current) => acc + current.checkItems.length, 0);
    return {
      text: totalItemCount,
      icon: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAF2SURBVDhPtZMxT8JQEMfb0pI2xMbA0JWyNXQEJLHO7VrmfgAHTfgMLMTo0FknDU0TNze+gCbOSmSBwU2hgxMlAevd8wV95GG6+Euu73/v/e/aXlPhX8myrIBBUy4iXRmCIDicTqeeqqoHmKdp+lir1YaDweCeGHZx1u/vHTnOpWEYqSiKGWyRQI17juNc9cFDzNvEUay2ms1bkJtCXjTBE0WRCprFc70TTdO4Rb8DPa7rnoL+odfr6bZtP4HkFm0HeJ+xBrQg4WU+n7eSJLFR5wH8dfC3UJMGy+WyDJNGmQvwC4vFooyaNFAUZVUo/Pm5GdBbLBZXqEkD2Bjpuv6BOg/olSRpRNNv2u32NSzcoW0HeG9gJZAnQOx6/cKsVmc03YlZNWfgPacpi+/7rmma7yC5d8azDnhAb2AmNx6PJ77fGWqaqsmyvF8qleB19c9KpfJqWdZdo9E4juP4gdoJ3J8J6Xa7BgzXQr1er1/CMHwjBwyC8AW6vpgYpmCzMQAAAABJRU5ErkJggg==`, // for card front badges only
      color: null,
    }
  }
});

But What I get it this:

index.esm.js:216 TypeError: Cannot read properties of undefined (reading ‘length’)
at client.js:14:89
at Array.reduce ()
at card-badges (client.js:14:39)

TRELLO TEAM: This appears to be an issue with the t.card() ref we get in the card badge. This is a Bug!!!