According to http://chaijs.com/api/bdd/#a, a/an can be used to check for the type of a variable.
.a(type)
#param{ String } type
#param{ String } message _optional_
The a and an assertions are aliases that can be used
either as language chains or to assert a value's type.
However, I'm not able to check for the variable beeing an integer. The given examples, e.g. expect('1337').to.be.a('string'); work for me, but the following does not:
expect(42).to.be.an('integer');
expect(42).to.be.an('Integer');
expect(42).to.be.an('int');
expect(42).to.be.an('Int');
All of them are giving me the following error when running mocha:
Uncaught AssertionError: expected 42 to be an integer
How do I test with chai for a variable beeing an integer?
A bit late, but for people coming from search engines, here is another solution:
var expect = require('chai').expect
expect(foo).to.be.a('number')
expect(foo % 1).to.equal(0)
The number check is required because of things such as true % 1 === 0 or null % 1 === 0.
JavaScript doesn't have a separate integer type.
Everything is a IEE 754 floating point number, which would of type number.
This is also possible (at least whithin node):
expect(42).to.satisfy(Number.isInteger);
Here is a more advanced example:
expect({NUM: 1}).to.have.property('NUM').which.is.a('number').above(0).and.satisfy(Number.isInteger);
I feel your pain, this is what I came up with:
var assert = require('chai').assert;
describe('Something', function() {
it('should be an integer', function() {
var result = iShouldReturnInt();
assert.isNumber(result);
var isInt = result % 1 === 0;
assert(isInt, 'not an integer:' + result);
});
});
Depending on the browser/context you are running in there is also a function hanging off of Number that would be of some use.
var value = 42;
Number.isInteger(value).should.be.true;
It has not been adopted everywhere, but most of the places that matter (Chrome, FFox, Opera, Node)
More Info here
Another [not optimal] solution (why not?!)
const actual = String(val).match(/^\d+$/);
expect(actual).to.be.an('array');
expect(actual).to.have.lengthOf(1);
Related
Even when I save an integer to embedded data earlier in the survey flow (in previous blocks on different screens), I am not able in Javascript to get the embedded data value, ensure it is parsed as a number/integer, then use it in a loop. Is this something about TypeScript? I didn't see anything about parseInt or ParseInt in the TypeScript documentation.
For example, suppose I do the following:
// Draw a random number
var x = Math.floor(Math.random() * 5);
// Save it in embedded data
Qualtrics.SurveyEngine.setEmbeddedData("foo", x);
// In a later block on a different screen, get the embedded data as an integer
var x_new = "${e://Field/foo}"; // not an int
var x_new = parseInt("${e://Field/foo}"); // doesn't work
var x_new = ParseInt("${e://Field/foo}"); // doesn't work
// Loop using x_new:
for(i = 0; i < x_new; i++) {
console.log(i)
}
Any idea why this isn't working? Perhaps I just don't know how to parseint().
In "normal" JS runtime system, we have parseInt function, the function gets a string (like number string) as a parameter. In this env, we don't support your syntax - "${e://Field/foo}", because it is not a "number string".
In Qualtrics system environment they have parseInt too, but they support their custom syntax "${e://Field/foo}" to get EmbeddedData.
Make sure that your code is running on Qualtrics system environment.
ParseInt is just turning your string into an integer.
Look at the demo below.
let myVar = "${e://Field/foo}"; // This is a string
console.log(myVar); // This prints a string
console.log(parseInt(myVar)); // This prints "NaN", i.e. Not a Number, because the string isn't a representation of a number.
What if I want to store a very very large number and then display it. For example factorial of 200.
How can I do this using JavaScript?
I tried the normal way and the result is null or infinity.
function fact(input) {
if(input == 0) {
return 1;
}
return input * fact(input-1);
}
var result = fact(171);
console.log(result);
I tried in normal way and the result is infinity or null.
It seems JavaScript can generate Factorial up to 170.
Look at this picture. This calculator seems able to do it.
The BigInt numeric type is going to be implemented in the future of JavaScript, the proposal is on Stage 3 on the ECMAScript standardization process and it's being supported by major browsers now.
You can use either the BigInt constructor or the numeric literal by appending an n at the end of the number.
In older environments you can use a polyfill.
function fact(input) {
if(input == 0n) {
return 1n;
}
return input * fact(input-1n);
}
const result = fact(171n);
console.log(String(result));
Try this javascript based BigInteger library. There are many to choose from. But i recommend this one https://github.com/peterolson/BigInteger.js
Example:
var num = bigInt("9187239176928376598273465972639458726934756929837450")
.plus("78634075162394756297465927364597263489756289346592");
I'm doing my calculator and want prevent div to zero. I guess I must check last to elements if they are "/0"? what I'm doing wrong?
function div(input)
{
var input = document.getElementById("t");
var lastElement = (input.value.length-1);
//alert(input.value[lastElement-1]);
//alert(input.value[lastElement]);
if (input.value[lastElement-1] === "/")
{
if (input.value[lastElement] === "0")
{
alert(" / to Zero");
}
}
}
Use RegEx instead:
var is_div_by_zero = /\/[\s.0]+$/.test(value); // Returns true if it is divided by zero, false if otherwise
It matches:
/ 0
/0
/ 0
/ 000
/ 0.00000
etc.
As T.J. Crowder commented it is probably due to inconsistent formatting.
It would be better to work with the Javascript engine instead of going against it.
Just evaluate the entered formula and handle the exceptions thrown by the Javascript engine.
Place your evaluation code inside a try ... catch(e) block and handle the exceptions there.
try {
// your calculation code here, eg:
result = value1 / value2;
} catch (e) {
// this catches the error and provides the proper way of handling the errors,
// and your script doesn't die because of the error
// also, the e parameter contains the exception thrown, which provides info you can
// display
// or based on the error type come up with a proper solution
alert (e.message);
}
More info on Javascript error handling: http://javascript.info/tutorial/exceptions
Update
Forgot that, unfortunately, a division by zero does not result in an exception being thrown in Javascript. It will result in NaN for 0/0 and Infinity for x/0 (where x is any number). Infinity has the type number.
You can test for this after evaluating your equation.
My previous answer is one solution to your problem, but may bee too complicated for what would you like to achieve.
Instead of taking things from your input character by character, split your string on the operator and trim the parts. I will create the solution for two operands, and you can start from that.
var equation = document.getElementById("t").value;
var operands = equation.split('/');
var divisor = operands[operands.length - 1].trim();
// since the contents of your input are a string, the resulting element is also a string
if (parseFloat(divisor) == 0) {
alert("Division by zero");
}
This is a very rough approach, as you will have to validate and filter your input (no other things than numbers and valid operators should be allowed). Also, you will have to check for operation priority (do you allow multiple operators in your equation?) etc.
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
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