• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Javascript] Promise not working in classes?

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
What I want to do is:

Code:
class x extends y {
    constructor () {
        super();
        // do something depandant on super
    }
}


So I made some google searches and found something called promises which seems easy enough to use - I thought.

So I did the following:
Code:
class x extends y {
    test() {
        //do something
    }
    constructor() {
        super().then(function() {
            this.test();
        });
    }
}

and in the parent constructor:
Code:
return new Promise(function()
{
    //do stuff
});
However when I run the code, I get the error:
Uncaught (in promise) Typerror: Cannot set property tag of undefined
(in the constructor I use this.tag for a whole lot of stuff)

So my guess is that "this" gets broken for some reason, and I have no clue how to fix it.
I tried to add .bind but that gave a syntax error.
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Promises are a mechanism to make running asynchronous actions easier.
It has nothing to do with what you tried to write.
Since your code isn't asynchronous (unless your actual code is, in which case you should state so), execution always happens line by line.
JavaScript:
super();
this.test(); // Will always happen after super() returns

On a side note, you can use [code=javascript]...[/code].
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
What should I make the parent constructor return though?

edit: reversed the promise.

But now I notice that after super() nothing runs.

I did the following:

super();
console.log("yyy");

and in the parent constructor, the last line I do before returning "this" is:
console.log("done");

done gets written, but yyy does not, that is freaking me out.
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Whatever you want, however constructors generally shouldn't return anything.
JavaScript:
new x(); // what does x() return if not a new 'x'?

/Edit
I might have misunderstood you. If you mean how you should return a new 'x' from within 'x''s constructor, you don't need to. The "new" operator takes care of that.

Note that constructors are normal functions in every way, it's "new" that changes their behavior.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Why does a function need to return something in order for the proper execution of your code to continue?

You are calling a function called super(), and after that function returns (with a result or not, this doesn't matter), execution continues to the next line.

Read the edit in my previous message, that might be the cause of your confusion.

Can't tell what your edited error is without seeing code.
 
Last edited:

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Nope. I will post the whole ugly code, hopefully that will make it clear.

I have the class Chat which extends CustomWindow.

JavaScript:
const CustomWindow = require("./Window");

class Chat extends CustomWindow{

    test(x, y) {
        console.log("xxx"); //never happens either
        this.button = document.createElement("button");
        this.button.textContent = "Send";
        let buttonDiv = document.createElement("div");
        buttonDiv.setAttribute("class", "chatButton");
        buttonDiv.appendChild(this.button);
        buttonDiv.style.left = (x - 52) + "px";
        buttonDiv.style.top = (y - 37) + "px";

        let boxTag = document.createElement("div");
        boxTag.setAttribute("class", "chatBox");
        this.chatBox = document.createElement("input");
        this.chatBox.style.width = (x - 55) + "px";
        boxTag.appendChild(this.chatBox);
        this.tag.appendChild(buttonDiv);
        this.tag.appendChild(boxTag);
        this.chatBox.addEventListener("keypress", this.sendMsgEnter.bind(this));
        this.button.addEventListener("click", this.sendMsg.bind(this));
        this.socket.addEventListener("message", this.onResp.bind(this));
    }

    constructor(x, y, obj) {
        super(x, y, obj);
        console.log("yyyy"); //this never happens
        this.test(x, y);
    }
}

JavaScript:
//some irrelevant functions above
// CustomWindow's constructor
constructor(x, y, obj) {
        this.tag = document.createElement("div");
        this.tag.setAttribute("class", "chatWindow");
        this.tag.style.width = x + "px";
        this.tag.style.height = y + "px";

        this.headTag = document.createElement("div");
        this.headTag.setAttribute("class", "head");

        this.exit = document.createElement("img");
        this.exit.setAttribute("src", "../image/cross.png");

        this.icon = document.createElement("img");
        this.icon.setAttribute("src", obj.getAttribute("src"));
        this.icon.style.float = "left";

        this.headTag.appendChild(this.icon);
        this.headTag.appendChild(this.exit);

        this.tag.appendChild(this.headTag);

        this.tag.appendChild(this.headTag);

        this.main = document.querySelector("main");
        this.main.appendChild(this.tag);

        this.exit.addEventListener("click", this.onExit.bind(this));
        this.tag.addEventListener("click", this.onClick.bind(this));

        this.tag.addEventListener("mousemove", function (e) {
            if (e.buttons === 1) {
                this.style.top = e.pageY - (parseInt(this.style.height) / 2);
                this.style.left = e.pageX - (parseInt(this.style.width) / 2);
            }
        });

        this.socket = new WebSocket("ws://vhost3.lnu.se:20080/socket/");

        this.first;
        this.count = 0;

        console.log("done"); //this gets written out
    }
}
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Huh, honestly no clue from that code.

JavaScript:
class Parent {
    constructor(a) {
        console.log(a);
    }
}

class Child extends Parent {
    constructor(a, b) {
        super(a);
        console.log(b);
    }
}

new Child("a", "b");
// => a
// => b


Just as a side note, you access some DOM properties with simple JS object notation, and others with get/setAttribute.
You only need the latter for non-standard attributes.
E.g.
JavaScript:
this.tag.className = "chatWindow"; // one of if not the only DOM attribute with a different name, because "class" was a reserved word way before ES6 came into existence
...
this.exit.src = "../image/cross.png";
...
this.icon.src = obj.src;
 
Last edited:

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Ouch..

I found a workaround, I made a function in the parent class called addChat. This makes it work, but it's not as clean as I want it at all.

But at least it works t.t

edit: I MAY HAVE FOUND THE PROBLEM! If this shit is the problem I am gonna..

Yup, I found the problem...

When I used require in the module where created the I used require on the window module not the chat one.....

This is just embarrassing.
 
Last edited:
Status
Not open for further replies.
Top