Access to instance property from another .js file - javascript

I'd like to show for example some stats in HTML subpage that are stored in Class object that is created while clicking on the button.
class Game {
constructor(start) {
this.stats = new Statistics();
this.wallet = new Wallet(start);
document.querySelector('.start').addEventListener('click', this.startGame.bind(this));
}
And for example I want to see stats from stats variable on another subpage.
Can you give me any suggestions?

Likely you want to store this in a global variable.
For example (not necessarily good practice):
Game.js
var currentGame = null;
class Game {
constructor() {
currentGame = this;
this.stats = new Statistics();
// ....
}
}
Now, you can just access your currentGame instance, which presumably there will be only one of. To get better knowledge on how to implement this pattern in a better way, research the Singleton pattern.
console.log(currentGame.stats)

Related

find class instance by property in javascript

I'd like to retrieve an instance of some js Class with only the value of a parameter
lets say :
function myClass(id)
{
this.id = id
}
myClass.prototype.sayHello = function()
{
alert('hello');
}
myClass.instanceFromID = function()
{
...
}
var instance1 = new myClass(22);
var instance2 = new myClass(33);
var instance3 = new myClass(232);
var instance4 = new myClass(1533);
I would love to be able to access the instance by some method like
myClass.instanceFromID(33).sayHello();
I've been thinking of 2 solutions but they seam overkill :
First idea:
storing all the instances in an array, (global scope or static to the class) and iterating over all of them to find and return the instance, but this implies to keep track, add and remove the instances from the array.
Second idea:
make each instance listen to a custom event triggered from the document and compare the data emitted with inner parameter to check if it is concerned and emit a signal back to the document.
How can I achieve this in a simple way or is there no other way than these 2?
Based on what you've written, having the class itself keep track of instances with an instance variable seems to be the approach you're looking for. Of course, this means that instances will never be garbage collected unless you explicitly release them. But perhaps that isn't an issue for you. Here's how I would tackle this:
function MyClass(id) {
this.id = id;
MyClass.instances[id] = this;
}
MyClass.instances = {};
MyClass.instanceFromId = function(id) {
return MyClass.instances[id];
}

What is a proper way to create argument var names in a module for a new Class creation?

In the following code example I want to somehow create a var myThingName via a functions arguments so I can avoid having to build global var names outside of the Module.
I have tinkered with window['myvarname'] = "yada"; But that's a global and feels like a complete hack.
In short, I am assuming I need to have a way to make many vars like : myThingName_1 myThingName_2 etc...
Background: I am trying to build a Canvas Element constructor to put any number of individual Canvas elements onto the screen. I am using various libraries like Paper.js Kinetic.js etc. When trying to streamline the production I built a Module wrapper but am now stuck at how to create unique var names for the libraries KLASS constructor for their various implementations of stage or scope.
Perhaps I am doing things totally incorrectly from the start.
But at the moment I am stumped as to how this goes about or what the name of the pattern I am looking.
var MagicThingModule = {
createThing : function(myThingNameAsString){
var myThingName = myThingNameAsString;
myThingName = new KLASS.Shape({ // code });
},
init : function(myThingNameAsString){
createThing(myThingNameAsString);
}
}
MagicThingModule.init("sendNameForThing_1");
How about:
var MagicThingModule = {
allMyThings: {},
createThing : function(myThingNameAsString){
var myThingName = myThingNameAsString;
myThingName = new KLASS.Shape({ // code });
this.allMyThings[myThingNameAsString] = myThingName;
},
// use me to et your thing back...
getMyThing: function(myThingName){
return this.allMyThings[myThingName];
},
init : function(myThingNameAsString){
createThing(myThingNameAsString);
}
}
and you can later reference it by:
var myThing = MagicThingModule.getMyThing("sendNameForThing_1");

Create a copy of a module instead of an instance in Node.js

this would be my first question ever on stackoverflow, hope this goes well.
I've been working on a game (using corona SDK) and I used Node.js to write a small little server to handle some chat messages between my clients, no problems there.
Now I'm working on expanding this little server to do some more, and what I was thinking to do is create an external file (module) that will hold an object that has all the functions and variables I would need to represent a Room in my games "Lobby", where 2 people can go into to play one against the other, and each time I have 2 players ready to play, I would create a copy of this empty room for them, and then initialize the game in that room.
So I have an array in my main project file, where each cell is a room, and my plan was to import my module into that array, and then I can init the game in that specific "room", the players would play, the game will go on, and all would be well... but... my code in main.js:
var new_game_obj = require('./room.js');
games[room_id] = new_game_obj();
games[room_id].users = [user1_name,user2_name];
Now, in my room.js, I have something of the sort:
var game_logistics = {};
game_logistics.users = new Array();
game_logistics.return_users_count = function(){
return game_logistics.users.length;
}
module.exports = function() {
return game_logistics;
}
So far so good, and this work just fine, I can simply go:
games[room_id].return_users_count()
And I will get 0, or 1, or 2, depending of course how many users have joined this room.
The problems starts once I open a new room, since Node.js will instance the module I've created and not make a copy of it, if I now create a new room, even if I eliminated and/or deleted the old room, it will have all information from the old room which I've already updated, and not a new clean room. Example:
var new_game_obj = require('./room.js');
games["room_1"] = new_game_obj();
games["room_2"] = new_game_obj();
games["room_1"].users = ["yuval","lahav"];
_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
Even doing this:
var new_game_obj = require('./room.js');
games["room_1"] = new_game_obj();
var new_game_obj2 = require('./room.js');
games["room_2"] = new_game_obj2();
games["room_1"].users = ["yuval","lahav"];
_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
Gives the same result, it is all the same instance of the same module in all the "copies" I make of it.
So my question as simple as that, how do I create a "clean" copy of my original module instead of just instancing it over and over again and actually have just one messy room in the end?
What you're doing is this (replacing your require() call with what gets returned);
var new_game_obj = function() {
return game_logistics;
}
So, every time you call new_game_obj, you return the same instance of game_logistics.
Instead, you need to make new_game_obj return a new instance of game_logistics;
// room.js
function Game_Logistics() {
this.users = [];
this.return_users_count = function(){
return this.users.length;
};
}
module.exports = function() {
return new Game_Logistics();
}
This is quite a shift in mentality. You'll see that we're using new on Game_Logistics in module.exports to return a new instance of Game_Logistics each time it's called.
You'll also see that inside Game_Logistics, this is being used everywhere rather than Game_Logistics; this is to make sure we're referencing the correct instance of Game_Logistics rather than the constructor function.
I've also capitalized your game_logistics function to adhere to the widely-followed naming convention that constructor functions should be capitalized (more info).
Taking advantage of the prototype chain in JavaScript is recommended when you're working with multiple instances of functions. You can peruse various articles on "javascript prototypical inheritance* (e.g. this one), but for now, the above will accomplish what you need.

JavaScript private methods, asynchronous access

I'm using a pattern like the one shown below to create a javascript library that has private and public methods. The idea is that the page that includes this library would call MYLIB.login() and provide two functions for when the user clicks OK, or Cancel.
var MYLIB = function() {
// private data and functions
var showForm = function() {
// create and show the form
};
var onOK = function() {
// hide the form, do some internal stuff, then…
okFunction();
};
var onCancel = function() {
// hide the form, do some internal stuff, then...
cancelFunction();
};
var okFunction = null;
var cancelFunction = null;
// public functions
return {
login : function(okf, cancelf) {
okFunction = okf;
calcelFunction = cancelf;
showForm();
},
};
}();
My question is about getting the buttons in the form to call the internal functions onOK and onCancel, which are private. The buttons look like this:
<button onclick="onOK();">OK</button>
<button onclick="onCancel();">Cancel</button>
I can get it to work if I make the functions public, but then I may as well make everything public. How can I do what I want? Coming from a C++/Java background, trying to be a good OO guy. Thanks.
There are a lot of ways to go about it, but from what I see the onOK and onCancel have to be public because you need to access them from outside the class. You could vreate a public function to handel these actions like:
this.setStatus = function(status){
// check if the conection is on before calling the functions and stuff like that
if(status) onCancel();
else onOK();
}
it actually depends on where you want to go with this in the log run. Javascript provides a lot of OOP stuff, but is very different than C++/Java.
Tip: if you want to use private functions I would encourage you to use priviledgiat functions to work with the private methods (http://cuzztuts.blogspot.ro/search/label/oop) , also keep in mind that it's important the order in witch you declare your vars.

Get object by its `id` in an AIR windowedApplication

There may be a better way of doing this...so please suggest if there is.
I've got some javascript that calls an AIR function. This AIR functions creates a new HTML element and adds it to the "Stage" like so:
// guid is the ID given to the new window (HTML element) by javascript
private function createNewWindow(guid:String):void {
var frame:HTML = new HTML();
frame.id = guid;
addElement(frame);
}
Now I've also got a function that sets the location of the frame based on its id...this is where I'm struggling.
// set the location of the window referenced by it's id (guid)
private function setLocation(guid:String, location:String):void {
// psuedocode. Obviously it won't work.
stage.getById(guid).location = location;
}
So, how do I "get" my HTML element based on its ID?
Short answer, you don't. This isn't javascript, this is a OO language and as such, you need to change your thought process. What are you trying to do? Create several html windows within an air application? If you want to have an id based approach, you're going to need to store the id and the pointer to the component in an data structure (like a dictionary).
private var _components:Dictionary = new Dictionary();
this._components['someId'] = someComponent;
And from there you can add a function that just saves/returns the components. I'm not entirely sure what's your approach and what you're trying to accomplish, but my gut tells me you're not doing something right.

Categories