Parsing a string to true Integer in Javascript - javascript

I got a question about parsing a string to a true integer in javascript. I have a back-end method I've written that accepts an accountNumber (string) and a year (int), and I am calling into this method from the front-end.
The method complains unless it's being passed an actual int, and not a 'number'.
I've tried parsing my string a few ways:
const year = parseInt(stringValue);
typeof year == number
const year = Number.parseInt(stringValue);
Number.isInteger(year) == false
Number.isInteger(2018) == true
I even tried using the Math class, but with no luck.
const year = Math.floor(stringValue);
Where the year is still just a 'number'
In addition, I tried hard coding 2018 into my function and it worked as expected. I just can't seem to parse my value to a true integer and am wondering, how can I go about this? Or is it just recommended that I accept a string on the back-end and parse it there?
====== EDIT =======
I am trying it with AngularJS.
So I'm using angularJs and I got an with ng-model="account.searchDocsByYear", and I use the $scope value of account.searchDocsByYear as the argument for parsing. It still returns false. Not sure what is different. All the mentioned examples check out fine for me too. But console.log(Number.isInteger(Number.parseInt($scope.account.searchDocsByYear))); still returns false
Thanks!

You could use the Unary plus(+) for this purpose which is less verbose and attempts to convert its operand into a number, like this:
const stringValue = '2018';
const year = +stringValue;
console.log('Is integer: ' + Number.isInteger(year))

Working as expected.
See below snippet:
function ctrl($scope){
$scope.account = {
"searchDocsByYear" : "2018"
}
console.log(Number.isInteger(Number.parseInt($scope.account.searchDocsByYear)))
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="" ng-controller=ctrl>
</table>

Related

CAP framework CQL UPDATE with timestamp comparison or case-when statement

I am trying to UPDATE an entity set with a where condition containing the comparison of two timestamps. However, this is not working, as somehow the timestamps can't be compared (I don't get any hits no matter which manipulation I apply on the timestamps).
```UPDATE(CardReceiverAllocation).set({ isCurrentAllocation: true }).where({ card_ID: receiverEntryResult.card_ID, receiver_ID: receiverEntryResult.receiver_ID, timestamp: maxTimestamp })```
As an alternative I tried to write the UPDATE statement with an inclusive CASE WHEN statement, but this is generating the error "column is of type boolean but expression is of type text" even though I am returning boolean values in the statement.
```UPDATE`efa_CardReceiverAllocation`.set`isCurrentAllocation = ( case when timestamp = ( select max(timestamp) as maxTimestamp from efa.CardReceiverAllocation as CRA where CRA.receiver_ID = receiver_ID and CRA.card_ID = card_ID ) then true else false end )` ```
Does anybody know of a solution on how to achieve this update? Thank you in advance!

Return the date format for date without moment.js

I can't figure out how to build a function that does this
INPUT: dateToDateFormat('16/07/2022') -> OUTPUT: DD/MM/YYYY
INPUT: dateToDateFormat('07/16/2022') -> OUTPUT: MM/DD/YYYY
The input dates will be already formatted by .toLocaleString function
Edit:
I think I was not precise enough with the output, it should literally output MM/DD/YYYY as a string, not the actual date value
A) First of all, your desired date string conversion seems to be easy (solution below) without using any package/overhead.
B) However, if you need to process it further as a JS Date Object, things become more difficult. In this case, I like to provide some useful code snippets at least which might help you depending on your usecase is or what you are aiming for.
A) CONVERSION
Seems you need a simple swap of day and month in your date string?
In this case, you do not need to install and import the overhead of a package such as date-fns, moment or day.js.
You can use the following function:
const date1 = "16/07/2022"
const date2 = "07/16/2022"
const dateToDateFormat = (date) => {
const obj = date.split(/\//);
return `${obj[1]}/${obj[0]}/${obj[2]}`;
};
console.log("New date1:", dateToDateFormat(date1))
console.log("New date2:", dateToDateFormat(date2))
B) STRING TO DATE
Are you using your date results to simply render it as string in the frontend? In this case, the following part might be less relevant.
However, in case of processing them by using a JS Date Object, you should be aware of the following. Unfortunately, you will not be able to convert all of your desired date results/formats, here in this case date strings "16/07/2022" & "07/16/2022", with native or common JS methods to JS Date Objects in an easy way due to my understanding. Check and run the following code snippet to see what I mean:
const newDate1 = '07/16/2022'
const newDate2 = '16/07/2022'
const dateFormat1 = new Date(newDate1);
const dateFormat2 = new Date(newDate2);
console.log("dateFormat1", dateFormat1);
console.log("dateFormat2", dateFormat2);
dateFormat2 with its leading 16 results in an 'invalid date'. You can receive more details about this topic in Mozilla's documentation. Furthermore, dateFormat1 can be converted to a valid date format but the result is not correct as the day is the 15th and not 16th. This is because JS works with arrays in this case and they are zero-based. This means that JavaScript starts counting from zero when it indexes an array (... without going into further details).
CHECK VALIDITY
In general, if you need to further process a date string, here "16/07/2022" or "07/16/2022", by converting it to a JS Date Object, you can in any case check if you succeed and a simple conversion with JS methods provides a valid Date format with the following function. At least you have kind of a control over the 'invalid date' problem:
const newDate1 = '07/16/2022'
const newDate2 = '16/07/2022'
const dateFormat1 = new Date(newDate1);
const dateFormat2 = new Date(newDate2);
function isDateValidFormat(date) {
return date instanceof Date && !isNaN(date);
}
console.log("JS Date Object?", isDateValidFormat(dateFormat1));
console.log("JS Date Object?", isDateValidFormat(dateFormat2));
Now, what is the benefit? You can use this function for further processing of your date format depending on what you need it for. As I said, it will not help us too much as we still can have valid date formats but with a falsy output (15th instead of 16th).
CONVERT TO DATE OBJECT BY KNOWING THE FORMAT
The following function converts any of your provided kinds of dates ("MM/DD/YYYY" or "DD/MM/YYYY") to a valid JS Date Object and - at the same time - a correct date. However, drawback is that it assumes to know what kind of input is used; "MM/DD/YYYY" or "DD/MM/YYYY". The dilemma is, that this information is crucial. For example, JS does not know if, for example, "07/12/2022" is "MM/DD/YYYY" or "DD/MM/YYYY". It would return a wrong result.
const newDate1 = "07/16/2022"
const newDate2 = "16/07/2022"
function convertToValidDateObject(date, inputFormat) {
const obj = date.split(/\//);
const obj0 = Number(obj[0])
const obj1 = Number(obj[1])
const obj2 = obj[2]
//
// CHECK INPUT FORMAT
if (inputFormat === "MM/DD/YYYY") {
return new Date(obj2, obj0-1, obj1+1);
} else if (inputFormat === "DD/MM/YYYY") {
return new Date(obj2, obj1-1, obj0+1);
} else {
return "ERROR! Check, if your input is valid!"
}
}
console.log("newDate1:", convertToValidDateObject(newDate1, "MM/DD/YYYY"))
console.log("newDate2:", convertToValidDateObject(newDate2, "DD/MM/YYYY"))
console.log("newDate2:", convertToValidDateObject(newDate2, "MM/YYYY"))
If the wrong format is provided as a second argument, an error is provided in the console. In practise I suggest you to use a try-catch block ( I tried here, but it does not work here in this stackoverflow editor).
I wish you good luck. Hope these information can help you.

Ext.util.Format.number add extra decimals

I'm using method "Ext.util.Format.number" to convert a value to string, according to a specific format.
But this method add extra (parasite) decimal.
With this code :
var strValue = Ext.util.Format.number(value, this.displayFormat);
For example if
displayFormat = "0,000.00############"
value = 102.15
After conversion, strValue is not equals to 102.15 but to 102.15000000000001
Is there any way to be sure that "Ext.util.Format.number" never add extra/parasite decimal ?
Thanks
Since 102.15 and 102.15000000000001 are not distinguishable(*) in JavaScript, it's up to you to choose a number format that does not include that many digits. Ext.util.Format.number has no way to determine the correct output.
(*) try 102.15 === 102.15000000000001 in your javascript console - it returns true
Do parseFloat(strValue) after that formatting. I think thats what you are looking for.

razor engine syntax inside javascript tag for non string variables [duplicate]

Can someone format the code below so that I can set srcript variables with c# code using razor?
The below does not work, i've got it that way to make is easy for someone to help.
#{int proID = 123; int nonProID = 456;}
<script type="text/javascript">
#{
<text>
var nonID =#nonProID;
var proID= #proID;
window.nonID = #nonProID;
window.proID=#proID;
</text>
}
</script>
I am getting a design time error
You should take a look at the output that your razor page is resulting. Actually, you need to know what is executed by server-side and client-side. Try this:
#{
int proID = 123;
int nonProID = 456;
}
<script>
var nonID = #nonProID;
var proID = #proID;
window.nonID = #nonProID;
window.proID = #proID;
</script>
The output should be like this:
Depending what version of Visual Studio you are using, it point some highlights in the design-time for views with razor.
Since razor syntax errors can become problematic while you're working on the view, I totally get why you'd want to avoid them. Here's a couple other options.
<script type="text/javascript">
// #Model.Count is an int
var count = '#Model.Count';
var countInt = parseInt('#Model.ActiveLocsCount');
</script>
The quotes act as delimiters, so the razor parser is happy. But of course your C# int becomes a JS string in the first statement. For purists, the second option might be better.
If somebody has a better way of doing this without the razor syntax errors, in particular maintaining the type of the var, I'd love to see it!
This is how I solved the problem:
#{int proID = 123; int nonProID = 456;}
<script type="text/javascript">
var nonID = Number(#nonProID);
var proID = Number(#proID);
</script>
It is self-documenting and it doesn't involve conversion to and from text.
Note: be careful to use the Number() function not create new Number() objects - as the exactly equals operator may behave in a non-obvious way:
var y = new Number(123); // Note incorrect usage of "new"
var x = new Number(123);
alert(y === 123); // displays false
alert(x == y); // displays false
I've seen several approaches to working around the bug, and I ran some timing tests to see what works for speed (http://jsfiddle.net/5dwwy/)
Approaches:
Direct assignment
In this approach, the razor syntax is directly assigned to the variable. This is what throws the error. As a baseline, the JavaScript speed test simply does a straight assignment of a number to a variable.
Pass through `Number` constructor
In this approach, we wrap the razor syntax in a call to the `Number` constructor, as in `Number(#ViewBag.Value)`.
ParseInt
In this approach, the razor syntax is put inside quotes and passed to the `parseInt` function.
Value-returning function
In this approach, a function is created that simply takes the razor syntax as a parameter and returns it.
Type-checking function
In this approach, the function performs some basic type checking (looking for null, basically) and returns the value if it isn't null.
Procedure:
Using each approach mentioned above, a for-loop repeats each function call 10M times, getting the total time for the entire loop. Then, that for-loop is repeated 30 times to obtain an average time per 10M actions. These times were then compared to each other to determine which actions were faster than others.
Note that since it is JavaScript running, the actual numbers other people receive will differ, but the importance is not in the actual number, but how the numbers compare to the other numbers.
Results:
Using the Direct assignment approach, the average time to process 10M assignments was 98.033ms. Using the Number constructor yielded 1554.93ms per 10M. Similarly, the parseInt method took 1404.27ms. The two function calls took 97.5ms for the simple function and 101.4ms for the more complex function.
Conclusions:
The cleanest code to understand is the Direct assignment. However, because of the bug in Visual Studio, this reports an error and could cause issues with Intellisense and give a vague sense of being wrong.
The fastest code was the simple function call, but only by a slim margin. Since I didn't do further analysis, I do not know if this difference has a statistical significance. The type-checking function was also very fast, only slightly slower than a direct assignment, and includes the possibility that the variable may be null. It's not really practical, though, because even the basic function will return undefined if the parameter is undefined (null in razor syntax).
Parsing the razor value as an int and running it through the constructor were extremely slow, on the order of 15x slower than a direct assignment. Most likely the Number constructor is actually internally calling parseInt, which would explain why it takes longer than a simple parseInt. However, they do have the advantage of being more meaningful, without requiring an externally-defined (ie somewhere else in the file or application) function to execute, with the Number constructor actually minimizing the visible casting of an integer to a string.
Bottom line, these numbers were generated running through 10M iterations. On a single item, the speed is incalculably small. For most, simply running it through the Number constructor might be the most readable code, despite being the slowest.
#{
int proID = 123;
int nonProID = 456;
}
<script>
var nonID = '#nonProID';
var proID = '#proID';
window.nonID = '#nonProID';
window.proID = '#proID';
</script>
One of the easy way is:
<input type="hidden" id="SaleDateValue" value="#ViewBag.SaleDate" />
<input type="hidden" id="VoidItem" value="#Model.SecurityControl["VoidItem"].ToString()" />
And then get the value in javascript:
var SaleDate = document.getElementById('SaleDateValue').value;
var Item = document.getElementById('VoidItem').value;
I found a very clean solution that allows separate logic and GUI:
in your razor .cshtml page try this:
<body id="myId" data-my-variable="myValue">
...your page code here
</body>
in your .js file or .ts (if you use typeScript) to read stored value from your view put some like this (jquery library is required):
$("#myId").data("my-variable")
Not so much an answer as a cautionary tale: this was bugging me as well - and I thought I had a solution by pre-pending a zero and using the #(...) syntax. i.e your code would have been:
var nonID = 0#(nonProID);
var proID = 0#(proID);
Getting output like:
var nonId = 0123;
What I didn't realise was that this is how JavaScript (version 3) represents octal/base-8 numbers and is actually altering the value. Additionally, if you are using the "use strict"; command then it will break your code entirely as octal numbers have been removed.
I'm still looking for a proper solution to this.
It works if you do something like this:
var proID = #proID + 0;
Which produces code that is something like:
var proID = 4 + 0;
A bit odd for sure, but no more fake syntax errors at least.
Sadly the errors are still reported in VS2013, so this hasn't been properly addressed (yet).
I've been looking into this approach:
function getServerObject(serverObject) {
if (typeof serverObject === "undefined") {
return null;
}
return serverObject;
}
var itCameFromDotNet = getServerObject(#dotNetObject);
To me this seems to make it safer on the JS side... worst case you end up with a null variable.
This should cover all major types:
public class ViewBagUtils
{
public static string ToJavascriptValue(dynamic val)
{
if (val == null) return "null";
if (val is string) return val;
if (val is bool) return val.ToString().ToLower();
if (val is DateTime) return val.ToString();
if (double.TryParse(val.ToString(), out double dval)) return dval.ToString();
throw new ArgumentException("Could not convert value.");
}
}
And in your .cshtml file inside the <script> tag:
#using Namespace_Of_ViewBagUtils
const someValue = #ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue);
Note that for string values, you'll have to use the #ViewBagUtils expression inside single (or double) quotes, like so:
const someValue = "#ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue)";
I use a very simple function to solve syntax errors in body of JavaScript codes that mixed with Razor codes ;)
function n(num){return num;}
var nonID = n(#nonProID);
var proID= n(#proID);
This sets a JavaScript var for me directly from a web.config defined appSetting..
var pv = '#System.Web.Configuration.WebConfigurationManager.AppSettings["pv"]';
With
var jsVar = JSON.parse(#Html.Raw(Json.Serialize(razorObject)));
you can parse any razor object into a JavaScript object.
It's long but universal

Javascript Object not working with Native javascript methods like match(), replace etc

Here is the issue:
I go this Code:
var str = {"Acc":10 , "adm_data":"Denied"};
When I do something like:
console.log(str.Acc.match(/[0-9]+/g)) // To Get the Integer Value from the "Acc" key
Firebug Screams:
TypeError: str.Acc.match is not a function
console.log(str.Acc.match(/[0-9]+/g));
See Image:
I always do something like:
var str = "Hello _10";
console.log(str.match(/[0-9]+/g)) // This Works
Why is the Object thingi not working?
PLEASE NOTE:
As mentioned by #Fabrício Matté. The issue was that I was trying to
pass an integer Value to the .match method which does not belong
to integers. The solution was to do what #kundan Karn Suggested. Something like:
str.Acc.toString().match(/[0-9]+/g)// Converting it first to string then match. It worked!
match function works with string. So convert it to string first
str.Acc.toString().match(/[0-9]+/g)
It works just fine: http://jsfiddle.net/nKHLy/
but in order to get rid of the error you might want to try:
var str = {"Acc":"Hello_10" , "adm_data":"Denied"};
console.log(String(str.Acc).match(/[0-9]+/g));
or
var str = {"Acc":"Hello_10" , "adm_data":"Denied"};
console.log(str.Acc.toString().match(/[0-9]+/g));
To know the difference between the 2 options, check: What's the difference between String(value) vs value.toString()

Categories