0

I have the following structure:

appInterface = { 
  mainWinCanvas: document.getElementById("mainwindow"),
  mainWinContext: mainWinCanvas.getContext("2d"),
  mainWinCanvasWidth: mainWinCanvas.width,
  mainWinCanvasHeight: mainWinCanvas.height, 
  mainWinCanvasData: mainWinContext.getImageData(0, 0, mainWinCanvasWidth, mainWinCanvasHeight)
}

and get this error in Firebug: mainWinCanvas is not defined

What's causing it? I'm sure the script is called AFTER body element previous children are fully loaded. My goal is to make the code more readable, it's no-object version is working :(

8
  • So, what to do? Seems first commenter wiped the suggestion ... Commented Feb 16, 2014 at 14:13
  • Just replace the property name with document.getElementById("mainwindow")(can be also cached outside of object literal), or use a getter, or create the object using constructor function. Commented Feb 16, 2014 at 14:18
  • Yeah, but this adds too much letters to the code. The second idea is cool, but this means no well structured objects. The third seems will add more code. Commented Feb 16, 2014 at 14:24
  • 1
    Yes, it's allowed, though only one argument can be passed to setter. You can pass multiple values within an array or object ofcourse. Commented Feb 16, 2014 at 15:16
  • 1
    How would you set a value to a property without a value? Commented Feb 16, 2014 at 15:53

4 Answers 4

2

All you have to do is wrap this in a function and return it as object so the this context should be available to your current appInterface Object. Also convert your properties to methods, so you can able to do method chaining.

var appInterface = function () {
    return {
        canvas: null,
        ctx: null,
        mainWinCanvas: function (elem) {
            if (this.canvas === null) {
                this.canvas = document.getElementById(elem);
            }
            return this;
        },
        mainWinContext: function () {
            this.ctx = this.canvas.getContext("2d");
            return this;
        },
        mainWinCanvasWidth: function () {
            return this.canvas.width;
        },
        mainWinCanvasHeight: function () {
            return this.canvas.height;
        },
        mainWinCanvasData: function () {
            this.ctx.getImageData(0, 0, this.mainWinCanvasWidth(), this.mainWinCanvasHeight());
            return this;
        }
    };
};

Usage:

appInterface().mainWinCanvas('mainWindow').mainWinContext().mainWinCanvasWidth();
Sign up to request clarification or add additional context in comments.

3 Comments

This drops another TypeError: appInterface.CPanel is undefined while trying to add at document.body.onload appInterface.CPanel.addEventListener('click', function(){});
@Teemu This was not i was trying to post it was posted too earlier. By the way i forgot to convert properties into methods. Now it should work.
@RahilWazir Now your code is supposed to work. I didn't downvote, so I can't remove it either...
1

There's not much more coding, when creating an object with a constructor function:

function AppInterface (cnvid) { 
    this.mainWinCanvas = document.getElementById(cnvid);
    this.mainWinContext = this.mainWinCanvas.getContext("2d");
    this.mainWinCanvasWidth = this.mainWinCanvas.width;
    this.mainWinCanvasHeight = this.mainWinCanvas.height;
    this.mainWinCanvasData = this.mainWinContext.getImageData(0, 0, this.mainWinCanvasWidth, this.mainWinCanvasHeight);
}
var appInterface = new AppInterface("mainwindow");

You can even reuse the constructor, if you'd need more than one "appInterFace" in your app.

1 Comment

For the moment your answer is the clearest solution.
0

The object has no local context, you need to acces by its main reference appInterface

appInterface = { 
  mainWinCanvas: document.getElementById("mainwindow"),
  mainWinContext: appInterface.mainWinCanvas.getContext("2d"),
  mainWinCanvasWidth: appInterface.mainWinCanvas.width,
  mainWinCanvasHeight: appInterface.mainWinCanvas.height, 
  mainWinCanvasData: appInterface.mainWinContext.getImageData(0, 0, appInterface.mainWinCanvasWidth, appInterface.mainWinCanvasHeight)
}

If you want to have local context use functions instead

EDIT

use function constructor instead, you need a live instance for self referencing

var appInterface = new function(){
    this.test = 4;
};
appInterface = {
    anotherTest:appInterface.test
}

console.log(appInterface.test)

3 Comments

Have you tested this? Got appInterface is undefined
True, then with object is a no go, should be a function
For the mainWinContext I get TypeError: appInterface is undefined
0

One lame workaround to escape writting functions and getters/setters is to do the following:

appInterface = new Object();
appInerface.mainWinCanvas = document.getElementById("mainwindow");
appInerface.mainWinContext = appInerface.mainWinCanvas.getContext("2d");
...

This is stupid, i'm not deeply in JS but don't see the difference between new Object() and corresponging defining of its properties, or structure in the question ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.