Javascript: call object method using string only - javascript

This code doesn't work.
var Modal = {
init: function() {
console.log("test");
}
}
var objMethod = "Modal.init";
window[objMethod]();
I saw some answers that it can be called using this but I want to know how it can be called without using the object.
Modal["init"]();
Thank you!

To call a namespaced function, you need to use a multidimensional array. In this case it would be window['Modal']['init'](), which can also be expressed by splitting the objMethod string and using array indices:
var arr = objMethod.split(".");
window[arr[0]][arr[1]]();
var Modal = {
init: function() {
console.log("test");
}
}
var objMethod = "Modal.init";
var arr = objMethod.split(".");
window[arr[0]][arr[1]]();

Related

Adding properties to an object using function and bracket notation

I have an assignment on a basic javascript class that I'm taking and I can't seem to get this to work. I have this unit test that was given to me:
describe('AddSixthProperty', function() {
it('should add a food property with the value of bbq using bracket notation', function() {
expect(objects.addSixthProperty()['food']).to.equal('BBQ');
});
});
I was given an empty function:
// don't touch this line
var mysticalAnimal = objects.mysticalAnimal();
function addSixthElement(){
return
}
So I tried this:
var mysticalAnimal = objects.mysticalAnimal();
objects.addSixthProperty = function(){
mysticalAnimal['food'] = "bbq";
return mysticalAnimal["food"];
};
It doesn't work. Our test page doesn't pass that. Any help is greatly appreciated!
Thanks in advance!
You're returning mysticalAnimal['food'], and then the test tries to access ['food'] again, so it ends up accessing 'bbq'['food'], which is undefined. You need to just return mysticalAnimal, as well as get all your letter cases right. Here's a little proof of concept:
var objects = (function() {
var animal = { mystical: true };
return {
mysticalAnimal: function() { return animal; }
};
})();
var mysticalAnimal = objects.mysticalAnimal();
objects.addSixthProperty = function(){
mysticalAnimal['food'] = "bbq";
return mysticalAnimal;
};
var capturedAnimal = objects.addSixthProperty();
document.getElementById('result').innerText = capturedAnimal['food'];
<p id="result" />
Here is the function:
var mysticalAnimal = objects.mysticalAnimal();
objects.addSixthProperty = function(){
mysticalAnimal['food'] = "BBQ";
return mysticalAnimal;
};
// Test the function
console.log(objects.addSixthProperty()['food'])

Javascript return variables from each function

Looping through children elements using each.
var divHeights = [];
$('#parent').children('div').each(function () {
divHeights.push(this.clientHeight);
});
alert(divHeights); // fails
How can I return the divHeights variable?
I've tried
var hts = ('#parent').children('div').each(function () { ...
but obviously that won't work.
You can do this in better way using .map() like:-
var divHeights = $('#parent').children('div').map(function () {
return this.clientHeight || 0;
}).get();
DEMO FIDDLE
The divHeights variable is available all the time. You can just assign it to a variable whenever you want:
var hts = divHeights;
This will just be another reference to the array, so you can do that any time after the array is created, even before you have put any values into it:
var divHeights = [];
var hts = divHeights;
$('#parent').children('div').each(function () {
divHeights.push(this.clientHeight);
});
You can of couse just use the variable divHeights instead of the variable hts when you want to use the result, or just use the variable hts instead of divHeights from start.
You could make it into a function like this:
function getHeights() {
return $('#parent div').map(function() {
return this.clientHeight;
});
}
Then you can just call the function wherever you like to get the array contents.

OOJS call other method

var Lines = function(startXCon, endXCon,startYCon, endYCon)
{
this.drawCurve = function()
{
}
this.changeCurve = function(e)
{
//how can I call drawCurve from this method
}
}
The comment in my code explains the problem. Is this possible or are all methods private?
Like this:
var Lines = function(startXCon, endXCon,startYCon, endYCon){
var self = this; // store this as a variable to use in nested function
this.drawCurve = function(){}
this.changeCurve = function(e){
self.drawCurve(); //now call this.drawCurve()
}
}

Javascript class with jQuery and JSON

i'm creating a function that i wanna use as class on javascript.
My function, will call an JSON page create with php parse json, and set the vars, but it doesen't work.
May you can give me some hints?
Here's the code, thx in advance:
function SiteParams(){
$.getJSON("parse/parametri.php",function(data){
$.each(data,function(index,value){
this.NomeSito = value.nomesito;
this.URLSito = value.urlsito;
this.EmailAutore = value.email;
this.NomeAutore = value.nomeautore;
});
});
}
var website = new SiteParams();
function ModuleBase(){
$("<div/>",{id:"title", text:website.NomeSito}).appendTo("#main");
}
This is a good place to use $.Deferred
function SiteParams(){
// create a private deferred, and expose the promise:
var d = new $.Deferred();
this.load = d.promise();
var that = this;
$.getJSON("parse/parametri.php", function(data) {
// your $.each only used one value anyway
var value = data[0];
// copy the data across
that.NomeSito = value.nomesito;
that.URLSito = value.urlsito;
that.EmailAutore = value.email;
that.NomeAutore = value.nomeautore;
// resolve the promise
d.resolve();
});
}
var s = new SiteParams();
s.load.done(function() {
$("<div/>", {id:"title", text: s.NomeSito}).appendTo("#main");
});
You have the wrong this inside the callback to $.each (and the callback to getJSON). Try that:
function SiteParams(){
var that = this;
$.getJSON("parse/parametri.php",function(data){
$.each(data,function(index,value){
that.NomeSito = value.nomesito;
that.URLSito = value.urlsito;
that.EmailAutore = value.email;
that.NomeAutore = value.nomeautore;
});
});
}
Note that it doesn't make much sense to loop with each if your response only contains a single object. And if it contained multiple objects, every object would overwrite the previous. So, if your response is really an array with a single item inside, you can simple use this:
function SiteParams(){
var that = this;
$.getJSON("parse/parametri.php",function(data){
that.NomeSito = data[0].nomesito;
that.URLSito = data[0].urlsito;
that.EmailAutore = data[0].email;
that.NomeAutore = data[0].nomeautore;
});
}
getJSON is asynchronous, so you need to pass a callback function. Try this:
function SiteParams(cb){
$.getJSON("parse/parametri.php",function(data){
$.each(data,function(index,value){
this.NomeSito = value.nomesito;
this.URLSito = value.urlsito;
this.EmailAutore = value.email;
this.NomeAutore = value.nomeautore;
cb(this);
});
});
}
new SiteParams(ModuleBase);
function ModuleBase(website){
$("<div/>",{id:"title", text:website.NomeSito}).appendTo("#main");
}

Javascript array is undefined... and I'm not sure why

I'm trying to translate a PHP class into JavaScript. The only thing I'm having trouble with is getting an item out of an array variable. I've created a simple jsfiddle here. I cannot figure out why it won't work.
(EDIT: I updated this code to better reflect what I'm doing. Sorry for the previous mistake.)
function tattooEightBall() {
this.subjects = ['a bear', 'a tiger', 'a sailor'];
this.prediction = make_prediction();
var that = this;
function array_random_pick(somearray) {
//return array[array_rand(array)];
var length = somearray.length;
var random = somearray[Math.floor(Math.random()*somearray.length)];
return random;
}
function make_prediction() {
var prediction = array_random_pick(this.subjects);
return prediction;
}
}
var test = tattooEightBall();
document.write(test.prediction);
​
Works fine here, you are simple not calling
classname();
After you define the function.
Update
When you make a call to *make_prediction* , this will not be in scope. You are right on the money creating a that variable, use it on *make_prediction* :
var that = this;
this.prediction = make_prediction();
function make_prediction() {
var prediction = ''; //initialize it
prediction = prediction + array_random_pick(that.subjects);
return prediction;
}
You can see a working version here: http://jsfiddle.net/zKcpC/
This is actually pretty complex and I believe someone with more experience in Javascript may be able to clarify the situation.
Edit2: Douglas Crockfords explains it with these words:
By convention, we make a private that variable. This is used to make
the object available to the private methods. This is a workaround for
an error in the ECMAScript Language Specification which causes this to
be set incorrectly for inner functions.
To see the complete article head to: http://javascript.crockford.com/private.html
You never call classname. Seems to be working fine.
Works for me:
(function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
function pickone(somearray) {
var length = somearray.length;
var random = somearray[Math.floor(Math.random()*length)];
return random;
}
var random_item = pickone(this.list);
document.write(random_item);
}());
Were you actually calling the classname function? Note I wrapped your code block in:
([your_code]());
I'm not sure what you're trying to accomplish exactly with the class structure you were using so I made some guesses, but this code works by creating a classname object that has instance data and a pickone method:
function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
this.pickone = function() {
var length = this.list.length;
var random = this.list[Math.floor(Math.random()*length)];
return random;
}
}
var cls = new classname();
var random = cls.pickone();
You can play with it interactively here: http://jsfiddle.net/jfriend00/ReL2h/.
It's working fine for me: http://jsfiddle.net/YznSE/6/ You just didn't call classname(). If you don't call it, nothing will happen ;)
Make it into a self-executing function like this:
(function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
function pickone(somearray) {
var length = somearray.length; //<---WHY ISN'T THIS DEFINED??
var random = somearray[Math.floor(Math.random() * length)];
return random;
}
var random_item = pickone(this.list);
document.write(random_item);
})();
var test = tattooEightBall();
document.write(test.prediction);
Should be:
var test = new tattooEightBall(); //forgot new keyword to create object
document.write(test.prediction()); // forgot parens to fire method
and:
this.prediction = make_prediction();
Should be:
this.prediction = make_prediction;

Categories