0

I want store two variable with PopupMenu.PopupImageMenuItem object, and push them into an array, then want change the text of those popupmenuitems later every 10 seconds.

        var list = new Array();

        function add_timer (){
            //~ return function(){
            let d = parseInt(input.text);
            if(isNaN(d) || d < 1){return;}
            ...
            PopupMenu.PopupImageMenuItem.prototype.count = d;
            PopupMenu.PopupImageMenuItem.prototype.left = d;
            let item = new PopupMenu.PopupImageMenuItem(text, stock_icon.icon_name);
            ...
            that.menu.addMenuItem(item);
            list.push(item);
                var i = item;   log(i.count+' <====== '+i.left);
<======== here I got last input number is right one each time.
2 <====== 2
45 <====== 45
<=========================================
            //~ }
        }
//~ ---------------------------------------------------------
            GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10, () => {
                log("======"+list.length+"======");
                list.forEach((i)=>{
                    log(i.text +': '+ i.count+' <--- '+i.left);
<========= here I got undefined and error number. all number is last input one.
======2======
undefined: 45 <--- 45
undefined: 45 <--- 45
<======================
                })
                return GLib.SOURCE_CONTINUE;    //true
            });

It's like a closure problem, or error used prototype? or push works error? if the item in array is undefined, how can I get a list of PopupImageMenuItem object. My first time write js, so maybe it foolish problem. Please help.

eexpress
  • 386
  • 1
  • 14

1 Answers1

2

This seems like a bit of confusion with prototypes.

// This is a class
const MyClass = class {
    constructor() {
    }
};

// This is an object (class instance)
let myObject = new MyClass();

// This is how you set properties on an object
myObject.something = 32;


// This is how you set properties on a class
MyClass.prototype.something = 64;

// Now all new objects will have "something"
let myOtherObject = new MyClass();

if (myOtherObject.something === 64)
    log('True!');


// If you change the prototype, all new and current
// objects will have the new value
MyClass.prototype.something = 128;

if (myOtherObject.something === 128)
    log('True!');

if (new MyClass().something === 128)
    log('True!');

Probably you want to do something like this:

// Pro-tip: never use `var` unless you know you have to.
//
// Use `let` if you need to re-assign the variable later,
// like `list = <something else>`, otherwise use `const`.
const list = [];

function add_timer() {
    const d = Number.parseInt(input.text);
    
    if (Number.isNaN(d) || d < 1)
        return;

    const item = new PopupMenu.PopupImageMenuItem(text, stock_icon.icon_name);
    item.count = d;
    item.left = d;
    that.menu.addMenuItem(item);

    // Remove the item from the list if it is destroyed
    list.push(item);

    item.connect('destroy', (actor) => {
        list.splice(list.indexOf(actor), 1);
    });
}

// Save the timer ID somewhere so you can remove it later
let timerId = GLib.timeout_add_seconds(10, () => {
    // Or maybe remove the timer when there are no items
    if (list.length === 0) {
        timerId = 0;
        return GLib.SOURCE_REMOVE;
    }

    // NOTE: use `of`, not `in` like Python
    for (const item of list)
        log(`${item.label.text}: ${item.count} <--- ${item.left}`);

    return GLib.SOURCE_CONTINUE;
});

// To remove the timeout source by ID
if (timerId > 0)
    GLib.Source.remove(timerId);
andy.holmes
  • 3,383
  • 17
  • 28
  • 1
    Very thanks. It works perfect. I admire you for doing so easily. I will take a moment to fully understand each line. – eexpress Dec 30 '21 at 03:45
  • item.text = undefined, any advise. count and left is OK. – eexpress Dec 30 '21 at 04:08
  • 1
    Have a look through https://github.com/GNOME/gnome-shell/blob/main/js/ui/popupMenu.js too see how these classes work. You probably want `item.label.text`. – andy.holmes Dec 30 '21 at 04:12