Cannot init an object in jquery document.ready - javascript

I have an javascript object named concept:
function concept() {
this.ConceptId = 0;
this.Name = "";
}
I am trying to initiate it in jQuery document.ready:
$(document).ready(function() {
var concept = new concept;
});
It returns an error:
Uncaught TypeError: concept is not a constructor
If I move the object inside the document.ready, it is working.
$(document).ready(function() {
function concept() {
this.ConceptId = 0;
this.Name = "";
}
var concept = new concept;
});
I am still new on javascript, as far as I understood document.ready is run when DOM is completed. I don't understand why it cannot access the object which is defined out of the document.ready scope.
Here it is the fiddle: https://jsfiddle.net/49rkcaud/1/

The issue is because you're redefining concept. You just need to change the name of the variable:
$(document).ready(function() {
var foo = new concept; // change the variable name here
alert(foo.ConceptId); // = 0
});
function concept() {
this.ConceptId = 0;
this.Name = "";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Try this:
Jsfiddle: https://jsfiddle.net/3w284mcs/
$(document).ready(function() {
var concept = function() {
this.ConceptId = 0;
this.Name = "";
}
var concept_obj = new concept();
alert(concept_obj.ConceptId);
});

You just need to change variable name where call this function.
Answer
$(document).ready(function() {
/*function concept() {
this.ConceptId = 0;
this.Name = "";
}*/
var concept1 = new concept;
alert(concept1.ConceptId);
});
function concept() {
this.ConceptId = 5;
this.Name = "";
}
Better Approach
You should create object of function using ()
var objConcetp = new concept();
Also use constructor rather than directly assigning values. Your function look like:
$(document).ready(function(){
var oConcept = new concept(1, "YourName");
});
function concept(conceptId, name){
this.ConceptId = conceptId;
this.Name = name;
}

Related

How to overwrite default value from properties of this object with call or apply method in JS

I've started learning call, apply and bind and now i want to use it but have some problems:
I have a function:
let addTableRow = function() {
let template = HtmlTemplatesTelephony.ks.renderTableRow;
this.id = "";
this.creationDate = "";
this.address = "";
this.numberOfUser = "";
this.accessExisting = true;
$(DOM.tableBodyContainer).append(template(this));
};
I declared the this properties as default values
Here i invoke the function either with .call() or without:
let updateTable = function() {
let locations = userData().locations;
if(locations.length > 0) {
for(let location of locations) {
UIController.addLocation.call(location);
}
} else {
UIController.addLocation();
}
};
My idea was to use the 'this' values in the 'addTableRow' as default values in case of invoking the function without .call(). And when calling it with .call() I want to overwrite the 'this' default values. But exactly the opposite happens.
I know I could pass the object as parameter and set default object, but is there an other way to do it with .call()? Or is it the wrong use case for .call()?
Thanks for help!
***** UPDATE ******
Sorry, it is written in module pattern and i forgot to mention that the function 'addTableRow' is called 'addLoaction' in the return object. Here's some more code:
My UI controller:
let UIController = (function() {
let DOM = {
tableHeadContainer: $('thead'),
tableBodyContainer: $('tbody'),
inputNumberLocations: $('#numberLocations'),
inputAddress: $('.js-location-address'),
inputUser: $('.js-location-user'),
inputVpn: $('.js-location-vpn'),
btnDeleteLocation: $('.js-delete-location'),
};
let addTableRow = function() {
let template = HtmlTemplatesTelephony.ks.renderTableRow;
this.id = "";
this.creationDate = "";
this.address = "";
this.numberOfUser = "";
this.accessExisting = true;
$(DOM.tableBodyContainer).append(template(this));
};
return {
getDOM: DOM,
addLocation: addTableRow,
removeLocation: removeTableRow
}
})();
And my main controller:
let Controller = (function(dataController, UIController) {
let updateTable = function() {
let locations = userData().locations; // locations has the same properties as in function 'addTableTow'
if(locations.length > 0) {
for(let location of locations) {
UIController.addLocation.call(location);
}
} else {
UIController.addLocation();
}
};
return {
init: function() {
setupEventListeners();
updateTable();
},
}
})(dataController, UIController);
I hope it's more clear now.
When you .call(obj), you are starting your function with this being equal to that object. When you say this.id = "", you are overriding the id that you already had.
This may be a solution to your problem:
if (!this.id) {
this.id = "";
}
if (!this.property) {
this.property = "default";
}
// etc.

Access object property within a callback

I wrote the following code:
var Request = require('./request');
function Treasure(id) {
Treasure.prototype.valid = false;
Treasure.prototype.id = id;
Treasure.prototype.contentLength = 0;
Treasure.prototype.title = null;
Treasure.prototype.seller = null;
Treasure.prototype.buyer = null;
Treasure.prototype.cost = 0;
}
Treasure.prototype.loadData = function() {
EpvpRequest.treasureRequest(Treasure.prototype.id, function(data) {
if (data.valid) {
Treasure.prototype.valid = data.valid;
Treasure.prototype.contentLength = data.contentLength;
Treasure.prototype.title = data.title;
Treasure.prototype.seller = data.seller;
Treasure.prototype.buyer = data.buyer;
Treasure.prototype.cost = data.cost;
}
});
}
module.exports = Treasure;
Please don't hit me, I just started learning javascript.
I want ot access the properties of "Treasure"; but I can't use this, because I have a callback in the loadData function and this would refer to the function which called the callback - is that correct?
But it seems that I can't access the properties the way I tried with Treasure.prototype.property.
What is the correct way to to this?
First of all, you should be assigning instance variables in the constructor instead of assiginng to the prototype. The prototype is for methods and other things that will be shared by all Treasure instances.
function Treasure(id) {
this.valid = false;
this.id = id;
this.contentLength = 0;
this.title = null;
this.seller = null;
this.buyer = null;
this.cost = 0;
}
As for your problem with this inside callbacks, the usual workaround is to store the value of this in a regular variable and then use that variable inside the callback.
Treasure.prototype.loadData = function() {
// Nothing special about "that"
// Its just a regular variable.
var that = this;
EpvpRequest.treasureRequest(that.id, function(data) {
if (data.valid) {
that.valid = data.valid;
that.contentLength = data.contentLength;
that.title = data.title;
that.seller = data.seller;
that.buyer = data.buyer;
that.cost = data.cost;
}
});
}
Since this pattern comes up very often, some people choose to always use the same name for the "this-storage" variable. Some of the more popular names are self and that.

Error for JS OOP beginner training

I'm new in programming and I'm learning JavaScript OOP, trying to make a game with tanks. I have some code but it doesn't work properly and I need some help to understand how it works. Please check it and tell me how to solve the problem because I want to add a few more kinds of tanks but before that I need to fix the code.
var Tank = (function () {
function Tank(name) {
this._name = name;
}
Tank.prototype.getWeight = function () { return this._weight; }
Tank.prototype.getName = function () { return this._name; }
return Tank;
}());
var SmallTank = (function () {
this.prototype = Object.create(Tank.prototype);
function SmallTank(name) {
Tank.apply(this._name);
}
SmallTank.prototype._weight = 2;
return SmallTank;
}());
var myTank = new SmallTank("Aleks Tank");
console.log(myTank.getWeight());
It seems that you're just trying to do some kind of inheritance; typically you do this by assigning a parent instance to the prototype of the child.
I think you will want something like this:
var SmallTank = (function () {
function SmallTank(name) {
Tank.call(this, name);
this._weight = 2;
}
SmallTank.prototype = new Tank();
return SmallTank;
}());
Alternatively you can assign Object.create(Tank.prototype).
Here is another way of doing what it looks like you are attempting to do, following the Mozilla guide:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
var Tank = function (name) {
this.name = name;
};
Tank.prototype.getName = function () { return this.name; };
var SmallTank = function (name) {
Tank.call(this, name);
this.weight = 2;
};
SmallTank.prototype = Object.create(Tank.prototype);
SmallTank.prototype.constructor = SmallTank;
SmallTank.prototype.getWeight = function () { return this.weight; };
var myTank = new SmallTank("Aleks Tank");
console.log(myTank.getName());
console.log(myTank.getWeight());

TypeError: Object is undefined

In a code below:
var FilledObjectArray = function() {
this.filledObject = {};
};
FilledObjectArray.prototype = {
fill: function() {
this.filledObject["one"] = 1;
}
};
var SomeClass = function() {
this.something = new FilledObjectArray();
};
SomeClass.prototype = {
showContents: function() {
this.something.fill();
for (key in this.something) {
$("#some-div").append(this.something[key]);
}
}
};
$(document).ready(function() {
var s = new SomeClass();
$(".bla").each(function() {
$(this).click(function() {
s.showContents();
});
});
});
I'm getting this error in Firebug console:
TypeError: this.filledObject is undefined
this.filledObject["one"] = 1;
What I'm doing wrong here? From what I understand object is properly initialized and value assigning is correct. I'm testing this in Firefox 18.0.2 version and Chrome 25.
I think this should solve your problem
this.something.fill.call(this.something);
I found this issue with the existing code and have created a proposed solution, however I'm not exactly clear on your intent so it may be a little different than your needs, please modify as needed.
The Issue
The main issue stems from the FilledObjectArray object. This object's prototype is assigned a function fill and then assigned a property one of type int with a value of 1. So remember this object has two properties, one a function one an int.
So when you execute this code...
for (key in this.something) {
$("#some-div").append(this.something[key]); //Item 1
}
Two iterations of the loop occur, once for the function fill and once for the property one. The issue occurs on the iteration for the fill key, since this.something[key] is passed to the append(), which cann accept functions, causing jQuery to trigger the function. When this occurs, within the execution context of the fill function, this is assigned to #some-div, which does not have a filledObject property, causing the TypeError to be thrown. I have commented on some of this below:
var FilledObjectArray = function() {
this.filledObject = {}; //Fill is an object
};
FilledObjectArray.prototype = {
fill: function() {
this.filledObject["one"] = 1;
}
};
var SomeClass = function() {
this.something = new FilledObjectArray();
};
SomeClass.prototype = {
showContents: function() {
this.something.fill();
for (key in this.something) {
$("#some-div").append(this.something[key]); //The fill function is called here
}
}
};
$(document).ready(function() {
var s = new SomeClass();
$(".bla").each(function() {
$(this).click(function() {
s.showContents();
});
});
});
Proposed Solution
var FilledObjectArray = function() {
this.filledObject = [];
};
FilledObjectArray.prototype.fill = function(){
console.log(this);
this.filledObject[0] = 1;
};
var SomeClass = function() {
this.something = new FilledObjectArray();
};
SomeClass.prototype = {
showContents: function() {
this.something.fill();
for (var x = 0; x < this.something.filledObject.length; x++){
$("#some-div").append(this.something.filledObject[x]);
}
}
};
$(document).ready(function() {
var s = new SomeClass();
$(".bla").each(function() {
$(this).click(function() {
s.showContents();
});
});
});
i think you looking for this:
for (key in this.something) {
if(this.something.hasOwnProperty(key)){
$("#some-div").append(JSON.stringify(this.something[key]));
}
}
jsbin
you need use hasOwnProperty to iterate over the properties of an object without executing on inherit properties.
I feel a bit dumb right now but here is the solution to this:
SomeClass.prototype = {
showContents: function() {
this.something.fill();
for (key in this.something.filledObject) {
if (this.something.filledObject.hasOwnProperty(key)) {
$("#some-div").append(this.something.filledObject[key]);
}
}
}
};
I was trying to access object itself (this.something) instead of object property (this.something.filledObject)

Javascript object instance and document ready

This code gives me an error:
$(function(){
var instance = new object();
literal.call();
});
var literal ={
call : function(){
instance.foo();
}
}
function object(){
this.selector = $('div');
this.foo = function(){ this.selector.remove(); }
}
I want to make it run and I want to let the literal object out from $(function(){}). I don't want to change the selector at a later time.
So I discarded this solution
$(function(){
instance.selector = $('div');
literal.call();
});
var instance = new object();
var literal ={
call : function(){
instance.foo();
}
}
function object(){
this.selector = $('div');
this.foo = function(){ this.selector.remove(); }
}
And I discarded this also
$(function(){
var instance = new object();
var literal ={
call : function(){
instance.foo();
}
}
literal.call();
});
function object(){
this.selector = $('div');
this.foo = function(){ this.selector.remove(); }
}
what is the best practice to do this?
Your problem is that the istance variable was local to the ready handler. As you don't want to move your code in there (for whatever reasons), you will need to make the variable global:
var istance;
$(function(){
istance = new object();
literal.call();
});
var literal = {
call: function() {
istance.foo();
}
}
function object(){
this.selector = $('div');
this.foo = function(){ this.selector.remove(); }
}

Categories

Resources