How to properly use "this" within nested .each()(s)? (JQuery) [duplicate] - javascript

This question already has answers here:
JQuery nested this references [duplicate]
(4 answers)
Closed 7 years ago.
Here's my nested usage of .each:
itemData["segmentos"] = {};
$("[id^='item-segmentos-']").each(function() {
$("[id^='item-tipo-']").each(function() {
itemData["segmentos"][$(outerthis).val()] = $(innerthis).val();
});
});
How can I use the "outerthis" within the scope of the inner .each?

To use the 'outer' this in the inner each() loops, you simply have to cache the 'outer' this in a variable, and then refer to that variable in place of using this within the inner each() loops:
itemData["segmentos"] = {};
$("[id^='item-segmentos-']").each(function() {
var outerThis = $(this);
$("[id^='item-tipo-']").each(function() {
var innerThis = $(this);
itemData["segmentos"][outerThis.val()] = innerThis.val();
});
});

You can assign it to a variable in the outer function. This will form a closure and the inner function will have access to the outer variable:
itemData["segmentos"] = {};
$("[id^='item-segmentos-']").each(function() {
var outerthis = this;
$("[id^='item-tipo-']").each(function() {
itemData["segmentos"][$(outerthis).val()] = $(this).val();
});
});
But note that jQuery passes the index and element as parameters to your callback, which can make for clearer code, e.g.
itemData["segmentos"] = {};
$("[id^='item-segmentos-']").each(function(oIndex, outerElement) {
$("[id^='item-tipo-']").each(function(iIndex, innerElement) {
itemData["segmentos"][$(outerElement).val()] = $(innerElement).val();
});
});

Related

Javascript: call object method using string only

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]]();

Javascript Class, access property callback [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have the following javascript class similar to this:
class ModalFormButton {
constructor() {
this.contactForm = new ContactForm();
let utils = new Utils();
this.$signupModal = $(utils.getModalTmpl());
}
loadContactForm() {
this.$signupModal.modal();
this.contactForm.load();
}
contactBtnHandler(e) {
e.preventDefault();
let utils = new Utils();
var $t = $(this),
$modalTitle = $t.data('modal-title'),
$modalFormId = $t.data('modal-form-id');
$('body').append(this.$signupModal);
this.$signupModal.find('.modal-title').html($modalTitle);
this.$signupModal.find('.modal-body').load($t.attr('href') + ' #' + $modalFormId,this.loadContactForm);
};
registerHandlers() {
$('.modal-form-btn').click(this.contactBtnHandler);
};
load() {
this.registerHandlers();
};
}
My problem is that when contactBtnHandler is called I don't have access to class properties because the context belongs to modal-form-btn.
I know I can solve this using an arrow function, but I am wondering about if its possible to separate in a function the logic in the callback (here is a short example but I have longer functions) in a way similar to the one I am using.
Thanks
You can try binding "this" to your class in your callback handler
registerHandlers() {
$('.modal-form-btn').click(this.contactBtnHandler.bind(this) );
};
One could do:
getHandler (){
return e => {
//this is ModalFormButton
};
}
And then:
$('.modal-form-btn').click(this.getHandler());

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.

Accessing the parent object of a function in Javascript [duplicate]

This question already has answers here:
JavaScript - Owner of "this"
(6 answers)
Closed 8 years ago.
I have this function right here which takes the parts of my object and illuminates them successively with a delay (it switches the opacity of an element to 1 and then switches the previous element opacity to 0 to illuminate them successively).
The problem is that I cannot use the this keyword to access the parent objects parts in the illuminateInternal function.
This hinders any possible reuse of my object since I will have maleBackNoZoom and maleBackFullZoom objects.
I don't want to change the variable names of the illuminateInternal function when I re-use my object so I would like to use something like the this keyword in the illuminateInternal function as well.
maleBackNoZoom = {
parts:{
armsRight: findItemById("29") ,
armsLeft: findItemById("28"),
legsRight: findItemById("21"),
legsLeft: findItemById("22"),
back: findItemById("24"),
buttocks: findItemById("23"),
neck: findItemById("26"),
head: findItemById("27")
},
illuminate: function() {
var propertiesToIlluminate = [], prop, illuminateInternal, i = 0, delay = 200, intervalId;
for (prop in this.parts) {
propertiesToIlluminate.push(prop);
}
illuminateInternal = function () {
var property = propertiesToIlluminate[i];
var previousProperty = propertiesToIlluminate[i-1];
maleBackNoZoom.parts[property].opacity = 1;
console.log(previousProperty);
if (typeof previousProperty !== 'undefined'){
maleBackNoZoom.parts[previousProperty].opacity = 0;
}
paper.view.update();
i++;
if (i === propertiesToIlluminate.length) {
maleBackNoZoom.parts[property].opacity = 0;
clearInterval(intervalId);
setInterval(function(){paper.view.update()},delay);
}
};
intervalId = setInterval(illuminateInternal, delay);
}
}
You can define local variable inside illuminate method which will store reference to its object. And then you can use it as alias of this.
var self = this;
illuminateInternal = function () {
..
self.parts[property].opacity = 1;
}

How do I use a value outside of its function in JavaScript? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I have a function that calls a JSON string from another URL. The JSON is coming through fine and behaving as I want it to. The variable 'procode' is what I want to use outside the function, but I dont know how to pass the value of 'procode' up and out of the function completely, so I can use it on a global scale.
function(){
$.get('http://url-here/api/product', function(data) {
var rawcode = JSON.parse(data);
var procode = '"products":' + rawcode;
}, 'text');
}
Thanks in advance for any help :)
you need to set global variable to access it outside.Something like this:
var rawcode="";
var procode="";
function(){
$.get('http://url-here/api/product', function(data) {
rawcode = JSON.parse(data);
procode = '"products":' + rawcode;
}, 'text');
}
window.procode="";
var myFunction = function(){
var ajaxCall = $.get('http://url-here/api/product', function(data) {
var rawcode = JSON.parse(data);
window.procode= '"products":' + rawcode;
}, 'text');
$.when(ajaxCall).done(function(){
alert(window.procode);
});
};

Categories