Angular 2 - if condition getting true for all values - javascript

I have been stuck at a point, my if condition is returning true for all conditions, I am checking that a value is greater or not.
Code:
hideAmountModal() {
var self = this;
self.home_delivery_charge = self.storeService.fetchHomedeliveryData(self.shopId);
self.home_delivery_charge.subscribe((res: any) => {
for (var i = 0; i < res.length; i++) {
if (self.deliveryData.delivery_charge > res[i].amount) {
self.check_delivery_charge = true;
console.log('Deliverycharge',self.deliveryData.delivery_charge,'result',res[i].amount);
console.log('deliver charge is greater',self.check_delivery_charge);
}
else if (self.deliveryData.delivery_charge < res[i].amount){
self.check_delivery_charge = false;
}
}
})
self.DeliveryChargeValue = true
self.selectAmountModal.hide();
}
From the console what I get is below:
Where have I gone wrong?

Try converting both values to number type
if (parseInt(self.deliveryData.delivery_charge) > parseInt(res[i].amount)) {
}

Change your if condition from:
if (self.deliveryData.delivery_charge > res[i].amount)
To this:
if (Number(self.deliveryData.delivery_charge) > Number(res[i].amount))
Doing this, you would be explicitly type-casting your input type into number.
Remember: You'll get NaN (Not-a-Number) if your input can't be converted to number type.
In case you don't want this behavior you could always use parseInt which uses Javascript's Number() function under-the-hood as shown here.

Be careful because you are not handling the equal case, which you should include on the else if. Can you check that the values that you are comparing are numbers? This is probably the problem.

You console.log only value when is true
Try add console.log here :
else if(self.deliveryData.delivery_charge < res[i].amount) {
self.check_delivery_charge = false;
}

Related

charAt not evaluating

I am trying to write a function that will evaluate equality of characters in a string and return true if 3 in a row match. The charAt() doesn't seem to be working as the if statement always goes to the else block.
function myFunction(num1)
{
var checkNum1;
for (var i = 0; i < num1.length; i++)
{
if (num1.charAt(i) == num1.charAt(i+1) && num1.charAt(i) == num1.charAt(i+2))
{
checkNum1 = true;
break;
}
}
if (checkNum1 == true)
{
return true;
}
else
{
return false;
}
}
What should I be doing to get the last "if" block to return true?
The code that you have provided works fine with strings ie: myFunction("257986555213") returns true.
However, myFunction(257986555213) returns false as expected as charAt is a String method.
As a fail-safe approach, you can try adding the following line to your method at the beginning:
num1 += '';
This should convert your argument to string and you should get your results..
Hope it Helps!!

what is the order of boolean logic in Javascript?

I wanted to use two Not and one and in booleans to test if the variable is neither upper case nor lower case.
I used this code so far but it didn't work as required:
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toLowerCase()) ){
x.splice(x[i], 1);
}
This code was for a function that sorts entered strings yet uppercase are sorted first.
Here is the full code, I am also open to understanding better ways to create this function apart from boolean logic and the array methods I used.
function alpha(str){ // United States
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
for (var i = 0; i<x.length; i++){
if (x[i] == x[i].toUpperCase()){
cap.push(x[i]);
}
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toUpperCase()) ) {
x.splice(x[i], 1);
}
else {small.push(x[i]);}
}
var z = cap.sort();
var y = small.sort();
return z.concat(y).join("");
}
Please note the second else if statement is only useful because the code adds an empty space string at the beginning of the output, I'm not sure where it comes from, so please let me know if you have any idea how to sort this even without using the second else if.
In the ASCII table, upper case letters come first. That's why they come first when you sort alphabetically. Here's a link to a page on Wikipedia that shows the table with the upper case letters appearing first and their numerical equivalents. It's even printable.
Also, I took the liberty of simplifying your code a little. Seems like .splice() was not necessary.
function alpha( str ) {
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
var length = x.length;
for (var i = 0; i < length; i++) {
if (x[i] === x[i].toUpperCase()) {
cap.push(x[i]);
} else if (x[i] === x[i].toLowerCase()) {
small.push(x[i]);
}
}
return cap.sort().concat(small.sort()).join("");
}
Maybe explain what you're trying to do? It most likely has been done before in some form and you definitely came to the right place to find an answer.
Is this what you want to do?
var str = "United States";
function alpha(str) {
return str.split('').sort().join('');
}
alert(alpha(str));
In all programming languages (as far as i know), boolean expressions are always evaluated from the left to the right with brackets of course.
So in the following example my_func() is called first, and then if there is the chance that the complete expression becomes true my_other_func() is called
if (my_func() && my_other_func()) {
// I only get here if my_func() AND my_other_func() return true
// If my_func() returns false, my_other_func() is never called
}
The same is true for the "or" operator in the following example
if (my_func() || my_other_func()) {
// I only get here if my_func() OR my_other_func() return true
// If my_func() returns true, my_other_func() is not called
}
So back to your code, in details this part (I reformated it a bit for better readability):
if (x[i] == x[i].toUpperCase()){
// only uppercase here
cap.push(x[i]);
} else if (x[i] !== x[i].toUpperCase() && x[i] !== x[i].toUpperCase()) {
// tested twice the same thing, so Im really sure that its not uppercase :D
// only lowercase here
x.splice(x[i], 1);
} else {
// I will never reach this
small.push(x[i]);
}
Im not sure what you want to do, but I hope the comments help to understand your code.

HTML 5 toggling the contenteditable attribute with javascript

enter code hereI am trying to make something editable online with a function like this
function toggle_editable (div, cssclass) {
var classToEdit = document.getElementsByClassName(cssclass)
for (i = 0;classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
}
if (classToEdit[i].contentEditable == true) {
classToEdit[i].contentEditable = false ;
}
}
}
classToEdit is a collection of HTML elements with the same class name or whatever document.getElementsByClassName(cssclass) returns
when going through the debugger it jumps over the line
classToEdit[i].contentEditable == true
as well as over the line
classToEdit[i].contentEditable == true
and does not execute the code in the braces following the if statements
this works however - meaning it sets the contenteditable property without hesitation
classToEdit.contenteditable = true;
as well as this
classToEdit.contenteditable = false;
(well obviously)
also this seemed to have no effect
classToEdit.contenteditable = !classToEdit.contenteditable
ideas anyone?
ps why is the loop
You've created an infinite loop here:
for (i = 0;classToEdit.length; i++) {
Should be:
for (var i = 0; i < classToEdit.length; i++) {
But, if you say classToEdit.contenteditable = true "works", you've to define "not working/is working" since the snippet doesn't definitely do what you expect it to do, if classToEdit is a HTMLCollection.
It looks like you'd want to toggle contentEditable values, you can do it like this:
for (var i = 0; i < classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
} else { // Notice else here, no need for another check
classToEdit[i].contentEditable = false;
}
}
Or simply without ifs in the loop:
classToEdit[i].contentEditable = !classToEdit[i].contentEditable;
Your current code will switch the value back to it's original in a case the value was false.
HTMLElement.contentEditable returns a string and not a boolean.
Hence, what you want to identify the state of your editable field is:
// Incorrect
classToEdit[i].contentEditable == true
// Coorect
classToEdit[i].contentEditable === 'true'
What's even better if you want to know the state of your fields is to use HTMLElement.isContentEditable
which returns a boolean:
classToEdit[i].contentEditable = !element.isContentEditable
Another way to refactor the above:
function toggleContentEdit() {
var editableFields = document.getElementsByClassName('editable');
[].forEach.call(editableFields, function(field){
var isEditable = field.isContentEditable;
field.setAttribute('contenteditable', !isEditable);
});
};
JSFiddle: http://jsfiddle.net/6qz3aotv/

JavaScript Throws Undefined Error

What it is supposed to do -
Example
url1(pages,"ALT") returns "www.xyz.ac.uk"
url1(pages,"xyz") returns ""
The error - TypeError: Cannot call method 'toUpperCase' of undefined
This is just for some coursework, Im stuck with these errors. Any help would be much appreciated
function index(string,pattern,caseSensitive) {
if(caseSensitive == false) {
var v = string.toUpperCase();
} else {
var v = string;
}
return indexNumber = v.indexOf(pattern);
}
var pages = [ "|www.lboro.ac.uk|Loughborough University offers degree programmes and world class research.", "!www.xyz.ac.uk!An alternative University" , "%www%Yet another University"];
alert(url1(pages, "ALT"));
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
if(pages[i].indexOf(seperator)>0){
siteContent = pages[i].split(pages[i].indexOf(seperator));
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
}
}
if(pages[i].indexOf(seperator)>0){
siteContent = pages[i].split(pages[i].indexOf(seperator));
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
If pages[i].indexOf(seperator)<=0, siteContent is still whatever it was from the last iteration. If that happens on the first iteration, siteContent is still [], and siteContent[2] is undefined.
Another problem: the expression pages[i].indexOf(seperator) returns a number, and pages[i].split expects a delimiting string as an argument. Since the number doesn't appear in your input, you'll always get a single-element array, and siteContent[2] will always be undefined. Get rid of .indexOf(seperator), change it to siteContent = pages[i].split(seperator).
One more: get rid of the else { return ""; }. Add a return ""; after the for loop.
Finally, in the first if statement condition, change .indexOf(seperator) > 0 to .indexOf(seperator, 1) !== -1. Since you're getting seperator from the first character of the string, it will be found at 0. You want the second occurrence, so start the search at 1. In addition, .indexOf returns -1 if it doesn't find the substring. You'll need to account for this in both if conditions.
Side note, as this is not causing your problem: never use == false. JS will coerce stuff like 0 and "" to == false. If that's what you want, just use the ! operator, because the expression has nothing to do with the value false.
My final answer is http://jsfiddle.net/QF237/
Right here:
alert(url1(pages, ALT)); // ALT ISN'T DEFINED
I believe you forgot to quote it:
alert(url1(pages, "ALT"));
You should split the string passing the separator character itself. Your function then will look like:
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
console.log(seperator);
if(pages[i].indexOf(seperator)>=0){
siteContent = pages[i].split(seperator); //fixed here
}
console.log(siteContent);
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
}
}
Tell us if it worked, please.
EDIT: It seeems your index() also has a little problem. Please try the function below.
function index(string,pattern,caseSensitive) {
var v;
if(caseSensitive == false) {
v = string.toUpperCase();
pattern = pattern.toUpperCase(); //to clarify: pattern should be uppercased also if caseSensitiveness is false
} else {
v = string;
}
return v.indexOf(pattern);
}
EDIT 2:
And url1() is finally like this:
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
if(pages[i].indexOf(seperator)>=0){
siteContent = pages[i].split(seperator);
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}
}
return "";
}
In this case, the first occurrence of pattern in all pages will be returned.

Javascript behaving weirdly

the following function does not work as I thought it should have. For some reason, the loop breaks whenever one the the validate function returns false. Why is that?
Here is my code :
function validateGroup(input) {
if (!input.value.match(/^[0-9]{0,2}$/)) {
$(input).addClass("invalidField");
return false;
}
$(input).removeClass("invalidField");
return true;
}
function validateClass(input) {
if (!input.value.match(/^[a-zA-Z0-9-]{0,9}$/)) {
$(input).addClass("invalidField");
return false;
}
$(input).removeClass("invalidField");
return true;
}
function validateData() {
var rows = document.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
var valid = true;
for (var i = 0, arrayLength = rows.length; i < arrayLength; ++i) {
valid = valid && validateClass(rows[i].getElementsByTagName("input")[0]);
valid = valid && validateGroup(rows[i].getElementsByTagName("input")[1]);
valid = valid && validateGroup(rows[i].getElementsByTagName("input")[2]);
}
return valid;
}
Thanks a lot!
the statement valid && validateClass(...) will not call the validateClass method if valid is false. I think what you want to do is change the order of those to
valid = validateClass(rows[i].getElementsByTagName("input")[0]) && valid;
valid = validateGroup(rows[i].getElementsByTagName("input")[1]) && valid;
valid = validateGroup(rows[i].getElementsByTagName("input")[2]) && valid;
Javascript doesn't bother evaluating the rest of an && expression if it already knows that the result is false.
It looks like you want to run the validate functions on each iteration even if ‘valid’ was already set to false. However the && operation you are using will short-circuit, so although the loop will continue the validate functions will not be called on subsequent iterations.
A really simple alternative which would work the way you want would be:
for (var i = 0, arrayLength = rows.length; i < arrayLength; ++i) {
if(!validateClass(rows[i].getElementsByTagName("input")[0])) valid = false;
if(!validateGroup(rows[i].getElementsByTagName("input")[1])) valid = false;
if(!vvalidateGroup(rows[i].getElementsByTagName("input")[2])) valid = false;
}
It sounds like that is the intent of the function. The three lines of
valid = valid && validate...
mean that if any of the validate functions ever hits false valid will remain false for the rest of the loop.
I think it's because of the lazy evaluation scheme Javascript uses with &&. Try a single & instead.
Short-circuit evaluation: Support in common programming languages
It's called short-circuiting. Quick fix: replace each line with
valid = validateClass(rows[i].getElementsByTagName("input")[0]) && valid;

Categories