jQuery function returning undefined [duplicate] - javascript

This question already has answers here:
Return value from callback function
(2 answers)
Closed 9 years ago.
My function here is ever returnig undefined, what is wrong?
function getTaxType() {
$('.type').each(function() {
if ($(this).data('tax') === 'form1' && $(this).is(':checked')) {
return 'form1';
}
else if ($(this).data('tax') === 'form2' && $(this).is(':checked')) {
return 'form2';
}
else if ($(this).data('tax') === 'form3' && $(this).is(':checked')) {
return 'form3';
}
});
}

That's because you're returning from the callback function of $.each and not from getTaxType.
Try this:
function getTaxType() {
var result;
$('.type').each(function() {
if ($(this).data('tax') === 'form1' && $(this).is(':checked')) {
result = 'form1';
}
else if ($(this).data('tax') === 'form2' && $(this).is(':checked')) {
result = 'form2';
}
else if ($(this).data('tax') === 'form3' && $(this).is(':checked')) {
result = 'form3';
}
});
return result;
}

If it's checkboxes there can be more than one which means you have multiple results - storing this in array for you.
Multiple-Choice:
function getTaxType() {
var result = [];
$('.type:checked').each(function(i) {
var tax = $(this).data('tax');
result[i] = (tax === 'form1' || tax === 'form2' || tax === 'form3') ? tax : false;
});
return result;
};
If you meant to only have one result (radio button), then you remove the = [] on result and the [i] in the loop.
Single Answer
function getTaxType() {
var tax = $('.type:checked').data('tax');
var result = (tax === 'form1' || tax === 'form2' || tax === 'form3') ? tax : false;
return result;
};
Of course, if it is single answer (aka radio buttons) then you can ONLY have those three form answers which makes it even simpler:
function getTaxType() {
return $('.type:checked').data('tax');
};

Related

Return a value from a function within a function [duplicate]

This question already has answers here:
What does `return` keyword mean inside `forEach` function? [duplicate]
(2 answers)
Closed 1 year ago.
So, I have a function that is used to iterate over rows within a spreadsheet. Based on checking some values, I need to return a value, if not, shouldn't return. I don't know how to return only in the specific cases when the function(row) has a return value.
function GetOldAreaSize(ID, area_changed, change_doc, area_kha, sheetSource) {
var data = sheetSource.getDataRange().getValues();
data.forEach(function (row) {
if (row[0] == ID) {
var area_changed_old = row[4];
var change_doc_old = row[2]+row[3];
var area_kha_old = row[15];
if (area_changed == area_changed_old) {
if (change_doc == "MR1") {
if (change_doc_old == "PDD1") {
var old_area = parseFloat(area_kha_old);
Logger.log(old_area+" - "+parseFloat(area_kha))
return parseFloat(area_kha_old);
}} else if (change_doc == "MR2") {
if (change_doc_old == "MR1") {
Logger.log(area_kha_old+" - "+parseFloat(area_kha))
return parseFloat(area_kha_old);
}} else if (change_doc == "MR3") {
if (change_doc_old == "MR2") {
Logger.log(area_kha_old+" - "+parseFloat(area_kha))
return parseFloat(area_kha_old);
}} else if (change_doc == "MR4") {
if (change_doc_old == "MR3") {
Logger.log(area_kha_old+" - "+parseFloat(area_kha))
return parseFloat(area_kha_old);
}} else if (change_doc == "MR5") {
if (change_doc_old == "MR4") {
return parseFloat(area_kha_old);
}} else if (change_doc == "MR6") {
if (change_doc_old == "MR5") {
return parseFloat(area_kha_old);
}}
else {
;
}
}
} else{
;
}});
}
In JavaScript when nesting functions, you can't return from an inner function for the outer function.
I recommend using a for loop instead of .forEach():
let data = sheetSource.getDataRange().getValues();
for(let row of data) {
/* Your code */
}

How to write a state machine to solve the Count the smiley faces?

I have solved the problem Count the smiley faces:
Given an array (arr) as an argument complete the function countSmileys that should return the total number of smiling faces.
Rules for a smiling face:
Each smiley face must contain a valid pair of eyes. Eyes can be marked as : or ;
A smiley face can have a nose but it does not have to. Valid characters for a nose are - or ~
Every smiling face must have a smiling mouth that should be marked with either ) or D
No additional characters are allowed except for those mentioned.
Valid smiley face examples: :) :D ;-D :~)
Invalid smiley faces: ;( :> :} :]
Example
countSmileys([':)', ';(', ';}', ':-D']); // should return 2;
countSmileys([';D', ':-(', ':-)', ';~)']); // should return 3;
countSmileys([';]', ':[', ';*', ':$', ';-D']); // should return 1;
Note
In case of an empty array return 0. You will not be tested with invalid input (input will always be an array). Order of the face (eyes, nose, mouth) elements will always be the same.
Then when I look through the solutions I find that many people use regexp. Then I want write a state machine to implement regexp and solve this problem. But I failed. This is my code:
function countSmileys(smileys) {
let state = smileyHasValidEye;
return smileys.filter(smiley => {
for (let s of [...smiley]) {
state = state(s);
}
return state === true;
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return;
}
console.log(countSmileys([':)', ';(', ';}', ':-D']));
And the error I get is:
state = state(s);
^
TypeError: state is not a function
Then I debugged my code I found the procedure doesn't enter the smileyHasValidNose function. Then I don't know the reason.
The problem is you don't really reset state in between smileys. So the next smiley state will be true which you can't call (it's not a function).
You could use a local variable for state that resets it to the first function (the first step).
function countSmileys(smileys) {
let firstStep = smileyHasValidEye;
return smileys.filter(smiley => {
let state = firstStep;
for (let s of [...smiley]) {
state = state(s);
}
return state === true;
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return;
}
console.log(countSmileys([':)', ';(', ';}', ':-D']));
This code however, will error if there's more on the string besides the smiley (or a partial of the smiley).
I would change smileyHasValidMouth to return false if it doesn't detect a smiley. Just to be more consistent here...
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return false;
}
And adjust your loop to exit early if it finds a value that is not a function.
for (let s of [...smiley]) {
state = state(s);
if(typeof state !== 'function') return state;
}
function countSmileys(smileys) {
let firstStep = smileyHasValidEye;
return smileys.filter(smiley => {
let state = firstStep;
for (let s of [...smiley]) {
state = state(s);
if (typeof state !== 'function') return state;
}
}).length;
}
function smileyHasValidEye(s) {
if (s === ':' || s === ';') {
return smileyHasValidNose;
}
return smileyHasValidEye;
}
function smileyHasValidNose(s) {
if (s === '-' || s === '~') {
return smileyHasValidMouth;
}
return smileyHasValidMouth(s);
}
function smileyHasValidMouth(s) {
if (s === ')' || s === 'D') {
return true;
}
return false;
}
console.log(countSmileys([':~(', ':>', ':D', ':(', ':o>', ';)', ':)']));

How to make multiple conditions inside single filter

I am trying to make a filter based on checkboxes.
The thing is js ignoring other conditions inside filter when one is active
filterData() {
return this.airlines.filter(x => {
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
return x.itineraries[0][0].stops == 0;
}
if (this.filters.options[i] == 1) {
return x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
}
} else {
return x;
}
})
}
I know that return will stop the current loop, but is there any way to do it correctly?
Update-1: (When to filter record for every case checked OR case)
Replace for loop and all conditions in a single return by && for if and || condition for data:
var chbox = this.filters.options;
return $.inArray(0, chbox) != -1 && x.itineraries[0][0].stops == 0
|| $.inArray(1, chbox) != -1 && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
Hope this helps !!
$.inArray(value, arr) method will check for each checkboxes and will work for every checked ones .
Update-2 (When to filter record for every case checked AND case)
As per comment below, you are trying to use checkbox on demand so use below code:
var chbox = this.filters.options;
boolean condition = true;
if ($.inArray(0, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].stops == 0;
}
if ($.inArray(1, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
return condition;
Your filter function is returning an object, which ideally should be a boolean value. Please refactor the code as below.
filterData() {
return this.airlines.filter(x => {
let result = false;
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
result = x.itineraries[0][0].stops == 0;
break;
} else if (this.filters.options[i] == 1) {
result = x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
break;
}
}
}
return result;
})
}

Javascript If Condition not evaluating correctly

I have a section of code where a variable contains a particular string (here it's multiply), and when I check if the variable has that particular string, the condition always equates to false. I cannot find what I'm missing here.
// calculations
$scope.$watch('colInput.' + el.key, function () {
angular.forEach($scope.colInput[el.key], function (item, index) {
angular.forEach($scope.column[el.key], function (item_1, index_1) {
if (item.hasOwnProperty(item_1.key)) {
item[item_1.key].type = item_1.type;
item[item_1.key].id = item_1.id;
item[item_1.key].options = item_1.options;
}
else {
item[item_1.key] = {};
item[item_1.key].type = item_1.type;
item[item_1.key].id = item_1.id;
item[item_1.key].options = item_1.options;
}
})
angular.forEach(item, function (elem, key) { //each column of the row
var operand_1, operator, operand_2;
if (elem.type == 10) {
// analyzing the formula
elem.options.forEach(function (el, index) {
if (isNaN(el) && index == 1) {
operator = el;
} else if (isNaN(el) && index == 0) {
operand_1 = el;
} else if (isNaN(el) && index == 2) {
operand_2 = el;
} else if (!isNaN(el)) {
operand_2 = parseFloat(el);
}
})
console.log(operator, eval(operator === "multiply"), typeof operator);
if (operator == 'multiply') {
console.log("IF---")
elem.value = parseFloat(item[operand_1].value) * operand_2;
}
}
})
})
}, true)
It looks like your operator is an HTML element not a String.
The comparison with multiply will always be false.

Double Condition

It will make selection words starting with "p" and ending with "a". Why it didnt work?
function checkWord(word) {
if (word.charAt(0) = 'p' && word.charAt(word.length - 1) = 'a') {
return true;
} else {
return false;
}
= is used for assigning values, not checking them. Use == for checking the values and === for checking value and types. So, your code should be like:
function checkWord(word) {
if (word.charAt(0) === 'p' && word.charAt(word.length - 1) === 'a') {
return true;
} else {
return false;
}
This should do the trick.
You didn't put 2 equals to if you only put 1 equals you are assigning it and if you put 2 equals you're comparing it the. below code should help
/* Check weather the first letter is equals to p and the last letter is equals to a. */
function checkWord(word) {
let firstPAndLastA = false;
if(word != null){
if (word.charAt(0) == 'p' && word.charAt(word.length - 1) == 'a') {
firstPAndLastA = true;
} else {
firstPAndLastA = false;
}
}
return firstPAndLastA;
}
//Calling Function
console.log(checkWord("ppoa"))

Categories

Resources