Data changes after assigning to another variable - javascript

I work with Discord.js User object and Mongoose Schema. But the problem doesn't seems to be part of those.
var Message = require('../app/models/message'); //Mongoose Schema
...
var newMessage = new Message();
...
//taggedUser is an object containing all the info about user. id property contains user id which is number.
const taggedUser = message.mentions.users.first();
newMessage.message.to = taggedUser.id;
console.log(taggedUser.id);
console.log(newMessage.message.to);
The code above should assign user ID to Schema. Everything works, but...
442090269928849410
442090269928849400
Last 2 characters aren't the same among these variables now. How is this even possible? The = changed the actual data inside the variable?
In case it is Mongoose here is how Schema looks like:
var msgSchema = mongoose.Schema({
message : {
from : Number,
to : Number,
content : String,
time : Date
}
});
Edit:
If I change
to : Number,
to string:
to : String,
It works properly. I still need the answer on why does this work incorrectly with number. Right above the problematic line I have another id which works perfectly fine:
newMessage.message.from = msg.author.id;
I have already tried to parse taggedUser.id to integer or creating Number() object but that didn't help. So every time I turn taggedUser.id into a Number or parse it to int it changes to the slightly different number.
I don't know what to think. How can data change during the assignment?
If there is not enough data provided in the question please ask me and I'll add everything needed. I can't imagine what might be causing this bug.

9007199254740992 - Highest safe number in JS
442090269928849410 - Your integer (id)
The reason of that small variation is the 'Max precision' JavaScript can work with.
When you tried to use the id as a number it was affected by this and it changed because JavaScript can't be that precise.
If you see both numbers at the beginning of this answer you can see that they are separated by 2 characters, that is why only the 2 last character changed.
Basically your integer was affected by the max precision JS numbers can have.
Reference: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Number/MAX_SAFE_INTEGER

You might just be seeing an artifact of console.log running asynchronously. Try this:
console.log('' + taggedUser.id);
console.log('' + newMessage.message.to);
...and see if that makes any difference.

Related

What is the subtraction (-) operator is used for in JavaScript other than math? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
Im having a hard time to understand the use of (-) operator in JS for non math proposes.
I have the following code :
let jeff = (new URL(location).searchParams.get('jeff') || "No parameters.");
eval(`ma = "Ma name ${jeff}"`);
document.write(ma)
And the Following URL :
basic.html?jeff=%22-alert(1)-%22
Im having a hard time to understand how the alert is being raised.
Appreciate the help.
I was expecting to get a string printed and not the execution of alert function.
What is the subtraction operator - used for in JavaScript, other than math?
This is a strange question, but it’s not the real question you’re asking here.
I’m having a hard time to understand how the alert is being raised.
This is the actual concern.
If you don’t understand how a process like this works, it helps to go through it step by step.
Look at the first line:
let jeff = (new URL(location).searchParams.get("jeff") || "No parameters.");
The URL constructor stringifies its first argument and parses it as a URL.
location is the object that holds information about the current page’s URL.
It’s stringified as the full URL.
The searchParams property is a URLSearchParams object, which holds all the query parameters of the URL, such as ?jeff=%22-alert(1)-%22, in a structured, decoded way.
.get("jeff") attempts to get the value of the jeff parameter.
Note that URLs are subject to encoding.
%22 is the percent encoding of the quote character "; %2B is the percent encoding of the plus character +; + is the URL encoding of a single space ; and so on.
The || "No parameters." defaults to the string "No parameters." if the jeff parameter is empty or not present.
If your location is https://example.com/?jeff=%22-alert(1)-%22 The result, which is assigned to the variable jeff, is '"-alert(1)-"'.
Second line:
eval(`ma = "Ma name ${jeff}"`);
`ma = "Ma name ${jeff}"` is a template literal which interpolates the variable jeff into the rest of the string; the resulting string is 'ma = "Ma name "-alert(1)-""'.
eval executes strings as code.
So, effectively, this line says: ma = "Ma name "-alert(1)-"" (or somewhat cleaner: ma = "Ma name " - alert(1) - "";).
This subtracts alert(1) from "Ma name ", and then subtracts "" from that intermediate result.
In order to evaluate this, alert(1) is executed.
That’s how the alert window appears.
Both the intermediate and the final result are NaN, because they involve the return value from the alert, namely undefined.
NaN is then assigned to the variable ma.
Third line:
document.write(ma)
This just writes the resulting NaN (as the string "NaN") into the open document stream (or, if closed, opens a new one, then writes into it).
Run this snippet to examine the intermediate results.
Note that the eval and the reference to the real location have been removed in the snippet; this is just to give you a general idea of how intermediate results might be examined.
const locationHref = "https://example.com/?jeff=%22-alert(1)-%22",
urlObject = new URL(locationHref),
searchParams = urlObject.searchParams,
jeffParameter = searchParams.get("jeff"),
jeff = jeffParameter || "No parameters.",
jeffIfNotFound = null || "No parameters.",
interpolatedString = `ma = "Ma name ${jeff}"`;
console.log({
locationHref,
urlObject,
searchParams, // Look at this in your browser console; the Stack Snippet doesn’t show a very useful representation.
jeffParameter,
jeff,
jeffIfNotFound,
interpolatedString
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
Back to your first question:
What is the subtraction operator - used for in JavaScript, other than math?
There is nothing special about - in this code.
Try any of the operators in this query string: ?jeff=%22**alert(1)/alert(1)*alert(1)>>>~alert(1)^alert(1)===alert(1)||!alert(1)<%22, and many more; this’ll alert six times with the meaningless result 1.
The Subtraction Operator is only used for math.
Any other application is either a hack or meaningless.
Actually, I tried other operators like plus (+)
But you didn’t URL-encode it correctly.
new URLSearchParams("jeff=a+b").get("jeff"); // Result: "a b".
new URLSearchParams("jeff=a%2Bb").get("jeff"); // Result: "a+b".
new URLSearchParams("jeff=a%2Bb%25c%26%26d").get("jeff"); // Result: "a+b%c&&d".
The + works just the same way.
The important thing is that functions will execute in order to be evaluated.
If they’re somewhere in the middle of operators, then they’re the operands which will be evaluated; it doesn’t matter which operators are used (unless they’re short-circuiting, in which case evaluation may be skipped).

Replacing Variables in String at Runtime

Currently I am using the following to evaluate variables that are placed in strings at runtime:
newVal = eval("`" + newVal + "`");
So if I have the string:
"Hello from channel: ${erpVars["CommandChannel"]["name"]}"
And erpVars["CommandChannel"]["name"] has value home, then the resulting string is:
Hello from channel: home
There are other objects than just erpVars that could be holding matching values for the string, but this is just one example. It's also important to note that each string could have more than one variable that needs replacing.
I am trying to achieve the same thing without using eval(), as some of the variable values come from user input.
Your case sounds super nasty (you should never ever use eval in JS! It poses a major security threat! also it looks weird that you want to replace this sort of a string) and perhaps if you told me more about where you get your inputs from and in what form, then maybe we could find together a much better solution for this. On that note, this is how I would solve your issue in its current form.
const newVal = 'Hello from channel: ${erpVars["CommandChannel"]["name"]}';
const strings = {
erpVars: {
CommandChannel: {
name: "home"
}
}
};
const vars = newVal.match(/\$\{.+?\}/g);
let result = newVal;
vars.forEach(v => {
let valuePath = '${erpVars["CommandChannel"]["name"]}'.match(/[\w\d]+/g).join('.');
result = result.replace(v, _.get(strings, valuePath));
});
console.log(result);
Note that I'm skipping here the edge scenarios, like getting a null result from the newVal.match when there are no variables in the newVal, but that's easy to handle.
Also note that over here i'm using the lodash library in _.get() (https://lodash.com/docs/4.17.15#get). It's super popular for this kind of small tasks. Of course there are really a lot of other tools that allow you to extract a value based on a property path like erpVars.CommandChannel.name that is stored in the valuePath variable, including a crazy amount of instructions that tell you how to do it yourself.

Using regex to test out of 4 words in an array has a perfect match

I was tasked with a project of creating a CV site were the user uploads a .docx file and the details is extracted from the file and is automatically inputted in the template designed by me,
I have been able to extract the details .docx file with JavaScript and the extracted details was kept in an array to make it easy to identify words with indexing. For example
[Adeola Emmanuel, adeolaemmanuel#gmail.com, pharmacist, 2 ketu ikorodu lagos, etc].
where i need help is not all CV uploaded by the user has the name coming first or email coming second but its sure that they come within 0,6 of the array so i decided to write a function that will help with that but its not working
var email = email(text.slice(0, 5));
function email(email) {
var re = /.{1,}#[^.]{1,}/ig;
if (!re.test(email)) {
email = text.slice(0, 1);
return email;
} else if (re.test(email)) {
email = text.slice(3, 5);
return email;
}
}
You can use the find array method:
function getEmail(arr) {
let re = /\S#[^.\s]/;
return arr.find(str => re.test(str));
}
let text = ["Adeola Emmanuel", "adeolaemmanuel#gmail.com", "pharmacist", "2 ketu ikorodu lagos"];
let email = getEmail(text.slice(0, 5));
console.log(email);
Some remarks:
{1,} in regular expressions can be shortened to just +
You actually don't need to test for multiple occurrences with +, since you would already accept one occurrence. So that also means you would be OK with just one non-point character after the #.
Neither of the regex suffixes (ig) have any use in your regex.
The .test method should get a string as argument, not an array. So you need to pass it email[0] for example.
For a full test of whether some string is a valid email address, the regular expression would be way more complex
When an if condition is false, there is no need to test the exact opposite in the else block: by exclusion that opposite condition will always be true when it gets executed.
The slice of an array is still an array, so returning text.slice(3, 5); in the else block does not make sense. You want to return a string.
You need a loop to inspect other array elements for as long as you don't have a match and have not reached the end of the array. So some loop construct is needed. You can use for, while, or any of the array methods that do such looping. find is particular useful in this case.
Don't give your function the same name as another variable (email) as only one value can be assigned to that variable (a function, a string, or still something else). So in your case you'll lose the function definition by the var initialisation.

Mirth - Add new field to OBR 16 segment

Got an opportunity to work in Mirth to add an entry in the OBR field.
With the help of this forum, I was able to edit an existing data, that works perfectly fine.
But failing to add a data to a field which doesn't exist in the source HL7.
Below is the example,
SourceHL7
PV2|||||||System Alert Off~0437689973~ABC-KOTHAI-AUS
OBR|1||ABCDEDFGH|754051^ABCEDEF^MDC|||20190225133500+0000||||||||||||||||||F
In the DestinationHL7, I want to check if PV2.7.2 has "KOTHAI", if yes, then update the OBR.16 as below
OBR|1||ABCDEDFGH|754051^ABCEDEF^MDC|||20190225133500+0000|||||||||KOTHAI|||||||||F
With the below Javascript, I am able to see the last value in OBR is changed as M but no "KOTHAI" is available. I could see the change in Transformed data but not in Encoded data. Could you let me know what am I doing wrong.
tmp=msg;
var code = tmp['ORU_R01.PATIENT_RESULT']['ORU_R01.PATIENT']['ORU_R01.VISIT']['PV2']['PV2.7'][2].toString();
if (code.indexOf("ARSTALL") != -1 )
{
tmp['ORU_R01.PATIENT_RESULT']['ORU_R01.ORDER_OBSERVATION']['OBR']['OBR.25'] = "M";
tmp['ORU_R01.PATIENT_RESULT']['ORU_R01.ORDER_OBSERVATION']['OBR']['OBR.16'] = "KOTHAI";
}else {
tmp['ORU_R01.PATIENT_RESULT']['ORU_R01.ORDER_OBSERVATION']['OBR']['OBR.25'] = "F";
}
Here is the same answer I gave on your forum post http://www.mirthcorp.com/community/forums/showthread.php?t=218996
You're using the strict parser, so you need to make sure everything is named correctly depending on hl7 datatype.
I think you want to do this:
tmp['ORU_R01.PATIENT_RESULT']['ORU_R01.ORDER_OBSERVATION']['OBR']['OBR.16']['XCN.1'] = "KOTHAI";

How to access the first two digits of a number

I want to access the first two digits of a number, and i have tried using substring, substr and slice but none of them work. It's throwing an error saying substring is not defined.
render() {
let trial123 = this.props.buildInfo["abc.version"];
var str = trial123.toString();
var strFirstThree = str.substring(0,3);
console.log(strFirstThree);
}
I have tried the above code
output of(above code)
trial123=19.0.0.1
I need only 19.0
How can i achieve this?
I would split it by dot and then take the first two elements:
const trial = "19.0.0.1"
console.log(trial.split(".").slice(0, 2).join("."))
// 19.0
You could just split and then join:
const [ first, second ] = trial123.split('.');
const result = [ first, second ].join('.');
I have added a code snippet of the work: (explanation comes after it, line by line).
function getFakePropValue(){
return Math.round(Math.random()) == 0 ? "19.0.0.1" : null;
}
let trial123 = getFakePropValue() || "";
//var str = trial123.toString();
// is the toString() really necessary? aren't you passing it along as a String already?
var strFirstThree = trial123.split('.');
//var strFirstThree = str.substring(0,3);
//I wouldn't use substring , what if the address 191.0.0.1 ?
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
Because you are using React, the props value was faked with the function getFakePropValue. The code inside is irrelevant, what I am doing is returning a String randomly, in case you have allowed in your React Component for the prop to be empty. This is to show how you an create minimal robust code to avoid having exceptions.
Moving on, the following is a safety net to make sure the variable trial123 always has a string value, even if it's "".
let trial123 = getFakePropValue() || "";
That means that if the function returns something like null , the boolean expression will execute the second apart, and return an empty string "" and that will be the value for trial123.
Moving on, the line where you convert to toString I have removed, I assume you are already getting the value in string format. Next.
var strFirstThree = trial123.split('.');
That creates an array where each position holds a part of the IP addrss. So 19.0.0.1 would become [19,0,0,1] that's thanks to the split by the delimiter . . Next.
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
This last piece of code uses the conditional if to make sure that my array has values before I try to splice it and join. The conditional is not to avoid an exception, since splice and join on empty arrays just returns an empty string. It's rather for you to be able to raise an error or something if needed. So if the array has values, I keep the first two positions with splice(0,2) and then join that array with a '.'. I recommend it more than the substr method you were going for because what if you get a number that's 191.0.0.1 then the substr would return the wrong string back, but with splice and join that would never happen.
Things to improve
I would strongly suggest using more human comprehensible variables (reflect their use in the code)
The right path for prop value checking is through Prop.Types, super easy to use, very helpful.
Happy coding!

Categories

Resources