t.closePopup not working (Error: No popover in context. Are you using the correct t?)

Hi again!

Could someone help us with this issue?

The closePopup function returns

Error: No popover in context. Are you using the correct t?

on the console.

document.getElementById('select-from-change-history').onclick = function(event) {

    var changeHistorySelections = [];

    // Get list of actions from REST API
    t.card('all')
        .then(function(card) {
            return apiGet(

                t,
                "1/cards/" + card.id + "/actions",
                function(actions) {

                    for (i = 0; i < actions.length; i++) {

                        // Get actions which destination list name is one of
                        // "Done", "Reviewed" or "Submitted"
                        if ('data' in actions[i]) {
                            if ('listAfter' in actions[i].data) {
                                if (doneListNames.includes(actions[i].data.listAfter.name)) {

                                    // Not defining this on actionDate first will make the value undefined on the callback
                                    var actionDate = actions[i].date;
                                    var changeInfo = actions[i].data.listBefore.name + " to " + actions[i].data.listAfter.name;
                                    changeInfo += " at " + formatDate(actions[i].date) + " " + formatTime(actions[i].date);
                                    changeInfo += " by " + actions[i].memberCreator.fullName;

                                    changeHistorySelections.push({
                                        text: changeInfo,
                                        callback: function() {
                                            updateCompletionDate(
                                                t,
                                                card,
                                                actionDate);

                                            // Update incentive values
                                            updateIncentive();

                                            t.closePopup(); // TO DO: Make this work
                                        }
                                    });
                                }
                            }
                        }
                    }
                    // If no action found with the above criteria,
                    // return a "No Completion Date History" list item
                    if (changeHistorySelections.length == 0) {
                        changeHistorySelections = [{
                            text: "No Completion Date History",
                            callback: function() {
                                t.closePopup(); // TO DO: Make this work
                            }
                        }]
                    }
                    t.popup({
                        mouseEvent: event,
                        title: 'Select Date from Change History',
                        items: changeHistorySelections,
                    });
                });
        });
}

*I am a newbie on JavaScript, so that, I would like to apologize beforehand if this is a stupid mistake.

Just realized that there is another issue here due to improper array handling inside the loop. As noted on the remarks, we pre-defined actionDate since if actions[i].date is defined directly on the callback, this would cause an undefined actions error.

However, turns out that on all the list callbacks, the effective actionDate is using the latest action on the loop. The intended actionDate should be the actions[i].date from each action.

Would appreciate any help from anyone experienced with JavaScript.

Are you running this inside of a capability callback handler? Or is this code running in an iframe in a pop up that has already been opened? If the latter, are you initializing the iframe properly?

var t = TrelloPowerUp.iframe();

It isn’t obvious where t is initially coming from.

The t is initially coming from var t = TrelloPowerUp.iframe(); defined in the same Javascript file with the card back section’s t.render().

The id ‘select-from-change-history’ is for a button in the card’s back section.

There is another issue we are currently facing that might also root from our lack of understanding in initializing t.

Suppose that:

  1. We have a file render.js file containing a function ‘theRenderFunction’ that should be called when rendering.
  2. We are trying to show a similar display on the card’s back-section and a modal opened from a card-button, in which both iframes are dependent on the same render.js file.
  3. The card back-section (back_section.js) and the modal (modal.js) has their own t initialized with t = TrelloPowerUp.iframe(); and then render is called with t.render(function() { theRenderFunction(); });

However, when t.set() is called due to a click in the modal page, the render only occurs in the back-section display while we expected that it occurs on both displays.

  1. The card back-section (back_section.js) and the modal (modal.js) has their own t initialized with t = TrelloPowerUp.iframe(); and then render is called with t.render(function() { theRenderFunction(); });

We have tried copy pasting the code inside theRenderFunction to t.render(function() { [THE CODE HERE] }); for both the back-section and the modal. However, the same not desired behavior occurs.

We figured out a bit more what might be happening, though, still has no solution for this issue.

RELEVANT HTML CODE:

back-section’s html:
<section id="approvals-section"></section>

<script src="{% static 'client.js' %}"></script>
<script src="{% static 'render.js' %}"></script>
<script src="{% static 'back_section.js' %}"></script>

modal’s html:
<section id="modal-approvals-section"></section>

<script src="{% static 'client.js' %}"></script>
<script src="{% static 'render.js' %}"></script>
<script src="{% static 'modal.js' %}"></script>

On theRenderFunction, we are updating the innerHTML of those sections.

var approvalsSectionElement = document.getElementById('approvals-section');
if (approvalsSectionElement != null) {
    console.log("Updating approvals-section HTML ..." )   
    approvalsSectionElement.innerHTML = html;
}
var modalApprovalsSectionElement = document.getElementById('modal-approvals-section');
if (modalApprovalsSectionElement != null) {
    console.log("Updating modal-approvals-section HTML ...")
    modalApprovalsSectionElement.innerHTML = html;
}

On each t.render() of back_section.js and modal.js, we logged when it is rendering.

The log shows that on the initial render after the card button is opened, the code successfully update the modal-approvals-section’s innerHTML while cannot find the approvals-section element. However, even though the modal is still opened, on the second render due to a user input (‘change’ eventListener), the code successfully find the ‘approvals-section’ element but cannot get the ‘modal-approvals-section’ element.

To summarize:

  1. Initial render (after opening modal)
    a. Expected behavior: The modal.js’ t.render() is the one being run. Besides that, both “Updating approvals-section HTML …” and “Updating modal-approvals-section HTML …” are logged.
    b. Apparent behavior: The modal.js’ t.render() is the one being run. However, only “Updating modal-approvals-section HTML …” is logged.
    c. This is not a functionality issue since we actually do not need the display in the back-section to be re-rendered. This is only our expected behavior based on the code.

  2. Next renders (on change triggers)
    a. Expected behavior: The modal.js’ t.render() is the one being run. Besides that, both “Updating approvals-section HTML …” and “Updating modal-approvals-section HTML …” are logged.
    b. Apparent behavior: The back_section.js’ t.render() is the one being run and only “Updating approvals-section HTML …” is logged.
    c. This is a functionality issue since the user cannot immediately view the expected settings changes on the modal display.

Are you using the same, single html file for rendering both the card back section as well as the modal?

They are differing html files.

Alright, I’ve been trying to get something going that we can use to reproduce the issue together.

I’ve put together this bare bones project that uses the card-back-section capability to render a card-back-section. For opening a modal, I’m using the card-buttons capability. Both of the iframes loaded by the section/modal use t.render() to console log when they find content on the page.

Power-Up enabled on public board: Trello
Glitch project: Glitch :・゚✧

Can you remix that project and get it to a place where it reproduces the issue?