Jquery .each() - return value undefined - javascript

Why getColorOptionSelect() return undefined value (I'm sure it has a value by debugger ).
It is for sure an issue related to the scope, sorry for my js ignorance
jQuery(document).ready(function () {
colorSelectID = getColorOptionSelect();
alert(colorSelectID);
function getColorOptionSelect() {
// get label
var selId;
jQuery(".product-options dl label").each(function () {
el = jQuery(this);
// lower case, remove *
var labelText = el.text().toLowerCase().replace("*", "");
if (labelText == 'color') {
//return element
selId = el.parent().next().find("select").attr('id');
return selId;
}
});
// return null;
}
});

getColorOptionSelect doesn't have an (uncommented) return statement.
The only return statement you have is inside the anonymous function you pass to each(). It will be consumed by the code underlying each() (which will stop looping if it is false).
This isn't a problem of scope, just of there being multiple functions.
You probably want to:
define a variable before you call each()
assign a value to it inside the each loop
return that variable at the end of getColorOptionSelect

You should do:
function getColorOptionSelect() {
// get label
var selId;
jQuery(".product-options dl label").each(function () {
el = jQuery(this);
// lower case, remove *
var labelText = el.text().toLowerCase().replace("*", "");
if (labelText == 'color') {
//return element
selId = el.parent().next().find("select").attr('id');
return false; // to stop further execution of each
}
});
return selId;
}
In your case you are doing return from callback function passed to each and it will not be passed from getColorOptionSelect
The only thing you can do returning a value from each function callback is to tell jquery if it should go to next item (return true;) or not (return false;)

Uncomment the last return statement to retun a value (something like selId)
jQuery(document).ready(function () {
colorSelectID = getColorOptionSelect();
alert(colorSelectID);
function getColorOptionSelect() {
// get label
var selId;
jQuery(".product-options dl label").each(function () {
el = jQuery(this);
// lower case, remove *
var labelText = el.text().toLowerCase().replace("*", "");
if (labelText == 'color') {
//return element
selId = el.parent().next().find("select").attr('id');
return false; //<--- return false to stop further propagation of each
}
});
return selId; //<--- Must return something
}
});

Related

Pass dynamic params to IIFE

I've got this issue with passing a variable to an IFFE. did some reading, still didn't figure it out. would really appreciate some guidance here.
i have a click event handler function that gets a certain ID from the
DOM when clicked.
i need to pass that ID to an IIFE
that IFFE needs to either add/remove that ID from an array,
depending if it's already there or not.
This is what I got:
Event:
$(document).on('click', 'input[type="checkbox"]', check);
Click Handler:
function check() {
var id = $(this).closest('ul').attr('data-id');
return id;
}
IIFE:
var checkID = (function (val) {
var arr = [];
return function () {
var i = arr.indexOf(val);
if (i === -1) {
arr.push(val);
} else {
arr.splice(i, 1);
}
return arr;
}
})(id);
right now i'm getting the ID, but returning it to nowhere.
in my IIFE, i did pass an id variable, but it's undefined.
so, how do I pass the ID variable im getting from check() to checkID IIFE?
other solutions are also welcome.
Thanks
In your clickHandler
function check() {
var id = $(this).closest('ul').attr('data-id');
checkID(id);
}
and change checkID to
var checkID = (function () {
var arr = [];
return function (val) {
var i = arr.indexOf(val);
if (i === -1) {
arr.push(val);
} else {
arr.splice(i, 1);
}
return arr;
}
})();
I think you need to do things sort of the other way around. Your check function would return a function used by the event handler, but it would also take a callback to be called after the click handler has run, passing your array.
The check function would look like a mash-up of both your functions:
function check(callback){
var arr = [];
return function(){
var id = $(this).closest('ul').attr('data-id');
var i = arr.indexOf(id);
if (i === -1) {
arr.push(id);
} else {
arr.splice(i, 1);
}
callback(arr);
}
}
As you can see, it takes as a parameter a callback function, which will be called on each execution, passing the current array arr. For example, this is my test callback:
function handler(arr){
alert("Array has " + arr.length + " elements");
}
Finally, your event handler would look like this:
$(document).on('click', 'input[type="checkbox"]', check(handler));
Live example: https://jsfiddle.net/src282d6/
Using getter/setter-like functions in your IIFE function makes it much more organized and readable. Then, use these functions to pass, store, and read data across your IIFE function.
var checkID = (function () {
// your array
var arr = [];
// public
return {
// get
getArray: function(){
return arr;
},
// set value
setArray: function(val) {
var i = arr.indexOf(val);
if (i === -1) {
arr.push(val);
} else {
arr.splice(i, 1);
}
}
}
})();
Use it as follows:
checkID.getArray(); // returns default empty array []
checkID.setArray('car1');
checkID.setArray('car2');
checkID.setArray('car3');
checkID.setArray('car4');
checkID.setArray('car4'); // test splice()
checkID.getArray(); // returns ["car1", "car2", "car3"]

How to quit an each() loop and return early from the outer function?

I am trying to return early from an event handler function if a certain condition is met (If the id selected is already in my question list.)
However I am not seeing the results that I expect.
When the condition is met I get the "I should return" message, but I am also getting the "did I still go here?" message. This is still allowing the rest of the code to execute in this function.
my.test.on('click', '.question-tagging .add-question-type', function() {
var questionIds = getSelectedQuestionIds();
console.log("questionIDs = " + questionIds);
var currentQuestions = $.each($('.question-list .question-item'), function () {
console.log("Question ID = " + $(this).find('.remove-tag').data('questionid'));
if (questionIds == $(this).find('.remove-tag').data('questionid'))
{
console.log("I should return");
return;
}
});
console.log("did i still go here?");
// more code...
});
Returning from each(), as you saw, isn't returning from the click handler. You can get what you want if you abandon each() for a simple for loop:
my.test.on('click', '.question-tagging .add-question-type', function() {
var questionIds = getSelectedQuestionIds();
console.log("questionIDs = " + questionIds);
var currentQuestions = $('.question-list .question-item');
for ( var i = 0; i < currentQuestions.length; ++i )
{
var q = $(currentQuestions[i]);
console.log("Question ID = " + q.find('.remove-tag').data('questionid'));
if (questionIds == q.find('.remove-tag').data('questionid'))
{
console.log("I should return");
return;
}
}
console.log("did i still go here?");
// more code...
});
return will only stop execution of the function it's in. In your case, it will stop execution of the loop, but not the outer click handling function. You can use a boolean flag to determine if you should continue with the outer function, like this:
my.test.on('click', '.question-tagging .add-question-type', function() {
var questionIds = getSelectedQuestionIds();
console.log("questionIDs = " + questionIds);
var shouldContinue = true; //set up a flag
var currentQuestions = $.each($('.question-list .question-item'), function () {
console.log("Question ID = " + $(this).find('.remove-tag').data('questionid'));
if (questionIds == $(this).find('.remove-tag').data('questionid'))
{
console.log("I should return");
shouldContinue = false; //flip the flag to false
return;
}
});
if( shouldContinue ) //only continue if condition wasn't met
{
console.log("did i still go here?");
// more code...
}
});
You have to use return false to break out of $.each loop. However, that will only break out of the loop callback and the control will be returned to the click handler function.
If you whish to return early from that function as well you will need another return statement in the click handler.

Javascript function returning undefined for template helper

Creating a template helper to return a variable to be displayed in the DOM, and my function is returning undefined and thus is not affecting the DOM. Not exactly sure why, though I feel as if it is a binding issue. Here's the code:
supportNumber: function(){
var jobSupportNumber = state.user.jobs.each(function(job){
console.log(jobOrder.get("jobId"));
console.log("test");
console.log(job.get("id"));
if(jobOrder.get("jobId") == job.get("id")){
var jobNumber = job.get("supportNumber");
console.log(jobNumber);
return jobNumber;
}
else{
console.log("this fired");
}
});
console.log(jobSupportNumber);
return jobSupportNumber;
}
I'm console logging alot to make sure values are being returned, and something is being returned all the way up until the final return statement, which returns jobSupportNumber as undefined. What am I doing wrong to have it return always as undefined?
.each() doesn't return the value of any of the function it's wrapping. The inner function results are only used to control the .each() loop.
Try this:
supportNumber: function(){
var jobSupportNumber = null;
state.user.jobs.each(function(job){
if(jobOrder.get("jobId") == job.get("id")){
jobSupportNumber = job.get("supportNumber");
return false; // tell .each() to quit looping
}
});
return jobSupportNumber;
}
By the code you have there, state.user.jobs.each() is not going to return jobNumber. That return applies to your anonymous function. (where you have function(job).
To get that value, you want something more like this:
supportNumber: function(){
var jobSupportNumber;
state.user.jobs.each(function(job){
console.log(jobOrder.get("jobId"));
console.log("test");
console.log(job.get("id"));
if(jobOrder.get("jobId") == job.get("id")){
var jobNumber = job.get("supportNumber");
console.log(jobNumber);
/* Set the value and just plain return, instead */
jobSupportNumber = jobNumber;
return;
}
else{
console.log("this fired");
}
});
console.log(jobSupportNumber);
return jobSupportNumber;
}

Get return value from given function using Jquery or Javascript

I have the Browser render source code in HTML following format.
There is button and on that button click one java-script function is called and I want the Return value from java script function.
Return value from that function.
Please refer below code for your reference,
Thanks,
Digambar K.
This is way to get return value using javascript:
function myFunction(value1,value2,value3)
{
}
var returnValue = myFunction("1",value2,value3);
if(returnValue.value1 && returnValue.value2)
{
//Do some stuff
}
This is way to get return value using jquery:
function getMachine(color, qty) {
var retval;
$("#getMachine li").each(function() {
var thisArray = $(this).text().split("~");
if(thisArray[0] == color&& qty>= parseInt(thisArray[1]) && qty<= parseInt(thisArray[2])) {
retval = thisArray[3];
return false;
}
});
return retval;
}
Use:
OnClientClick="return //javascript code"
instead of
onclick
Try this:
var returnValue;
$(document).ready (function(){
var myButton = $("#yourbuttonsid");
var originalEventHandler = myButton[0].onclick;
myButton.click(function(e) {
returnValue = originalEventHandler();
});
});
//Here you can do anything with returnValue

jquery - returning a value from function

say I have the following function:
function checkPanes() {
activePane = '';
var panels = $("#slider .box .panel");
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane = $(this).index()+1;
console.log(activePane);
}
});
} //END checkPanes();
Ideally, I'd like to call on this function elsewhere (most likely from another function),
and retrieve the value I am currently outputting to console.
(example ..)
function exampleCase() {
checkPanes(); //evidently, does not return anything.
//Ideally, I want the numerical value, being output to console in above function.
}
Thanks in advance! All suggestions / comments are well appreciated.
Cheers
Just noticed the loop; looks like what you may want to return is an array of all active panels (since in theory there could be more than one).
function checkPanes() {
activePanes = [];
var panels = $("#slider .box .panel");
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane.push($(this).index()+1);
console.log(activePane);
}
});
return activePanes;
}
If you know there will only ever be one active, you can go back to your original approach and just add return activePane after the console.log.
Forget everyone who says return activePane since they didn't see it's in a jQuery each loop. Won't work.
I'd suggest restructuring your selector. The selector you should be using is: $("#slider .box .panel:visible"). This will cut out your each loop entirely. For instance you could restructure the code as follows:
function checkPanes() {
return $("#slider .box .panel:visible").index();
}
function exampleCase() {
var visiblePane = checkPanes();
// ... do something with the index
}
I'd suggest just using the selector in-line rather than making a new function, but that's a matter of taste, especially if you have to select the same thing in multiple places.
Just switch your console line to a return statement:
function checkPanes() {
activePane = '';
var panels = $("#slider .box .panel");
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane = $(this).index()+1;
return activePane; // Return the value and leave the function
}
});
} //END checkPanes();
To call:
function exampleCase() {
var thepane = checkPanes(); //evidently, does not return anything.
// ...
}
I think it's as easy as using return activePane;
This:
function checkPanes() {
activePane = '';
var panels = $("#slider .box .panel");
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane = $(this).index()+1;
}
});
return activePane;
} //END checkPanes();
and this:
function exampleCase() {
var myval=checkPanes(); //evidently, does not return anything.
console.log(myval);
}
You can keep your code and just add a return if you want to use the values somewhere else
function checkPanes() {
activePane = '';
var panels = $("#slider .box .panel");
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane = $(this).index()+1;
console.log(activePane); //Logs to console.
return activePane; //Returns value also.
}
});
}
So in here you can either use the returned value or just have it log to console. Thats how i understood your question
function exampleCase() {
checkPanes(); //Now it will still write in console. but you dont need to use the return
alert(checkpanes()); //Would write it to console and to an alert!
}
But make sure you return string - or convert to string if you want to disaply it somewhere as text.
you have to return something inside the first function to manipulate it inside the second:
function checkPanes() {
activePane = '';
var panels = $("#slider .box .panel");
//create a return array
visiblePanels = [];
panels.each(function() {
//find the one in visible state.
if ($(this).is(":visible")) {
activePane = $(this).index()+1;
//add the result to the returnb array
visiblePanels[] = activePane
}
});
// return results
return visiblePanels;
}
function exampleCase() {
var thepane = checkPanes();
//now it has all the visible panels that were founded in the other function
// you can access them with thepane[0] or iterate on them
}
I think this is what you need.

Categories

Resources