JS if( item === ? ) statement not firing. Comparing issue - javascript

Purpose:
User inputs information. Script goes and checks if appendJSON.json has anything in its contents. Either returns the contents of .json or [].
Problem:
When comparing findNote === ''the if statment doesn't not fire off return [].
If there is something in appendJSON.json the else statment fires off like intented return findnote.
Attempts:
Tried comparing findNote to '', null and undefiend. Same outcome, what was returned was nothing.
1st Code-block: that accepts input then checks .json for any contents.
log to see what is coming back from fetchNotes()
function addNote(argv) {
const newSubmission = argv;
const getLibrary = fetchNotes().toString();
log(getLibrary);
}
2nd Code-block: fetchNotes():
function fetchNotes() {
const findNote = fs.readFileSync("./appendJSON.json");
if (findNote === "") {
return [];
} else {
return findNote;
}
}
I've tried slightly refactoring the code to remove the else statment:
function fetchNotes() {
const findNote = fs.readFileSync("./appendJSON.json");
if (findNote === "") {
return [];
}
return findNote;
}

Since you're not providing the encoding option, readFileSync returns a Buffer, not a string. A Buffer will never be === to ''. You probably wanted:
const findNote = fs.readFileSync('./appendJSON.json', 'utf8');
...but that assumes the contents are UTF-8, not (say) Windows-1252 or ISO-8859-1. Be sure you don't assume incorrectly, as you'll get corrupted characters for characters outside the ASCII range...
Side note: It seems quite odd to return an empty array if the file is empty, but a Buffer or string if it isn't.

Related

String Equality in Google Apps Script

I'm trying to compare a name retrieved from a JSON object, with a name as it exists on a google Sheet. Try as I might, I can't get a comparison that yields a positive.
I've tried:
IndexOf
localeCompare
==
===
I've tried
key===value
String(key)===String(value) and
String(key).valueof()=String(value).valueof.
I've also tried calling trim() on everything to make sure there are no leading/trailing white spaces (there aren't, as confirmed with a length() comparison.
As you can see from the screen shot, the values of key and value are exactly the same.
Any pointers would be gratefully received. This has held up my project for days!
Screenshot here
Description
This is not a solution but it might help find the problem. Perhaps the characters in one or the other is not what you think. Visually they compare, but what if one has a tab instead of a space. Try this, list the character codes for each and see if any character has a different value.
I've added another option that eliminates the for loop thanks to #TheMaster
Script (Option 1)
function test() {
try {
let text = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test").getRange("A1").getValue();
console.log(text);
let code = [];
for( let i=0; i<text.length; i++ ) {
code.push(text.charCodeAt(i))
}
console.log(code.join());
}
catch(err) {
console.log(err);
}
}
Script (Option 2)
function test() {
try {
let text = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test").getRange("A1").getValue();
console.log(text);
let code = [];
[...text].forEach( char => code.push(char.charCodeAt(0)) );
console.log(code.join());
}
catch(err) {
console.log(err);
}
}
Execution log
7:57:53 AM Notice Execution started
7:57:56 AM Info Archie White
7:57:56 AM Info 65,114,99,104,105,101,32,87,104,105,116,101
7:57:54 AM Notice Execution completed
Compare
function compare() {
const json = '{"values":[["good","bad","ugly"]]}';
const obj = JSON.parse(json);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const [hA,...vs] = sh.getDataRange().getDisplayValues();
let matches = [];
vs.forEach((r,i) => {
r.forEach((c,j) => {
let idx = obj.values[0].indexOf(c);
if(~idx) {
matches.push({row:i+1,col:j+1,index: idx});
}
})
})
Logger.log(JSON.stringify(matches))
}
Execution log
9:31:50 AM Notice Execution started
9:31:52 AM Info [{"row":1,"col":1,"index":0},{"row":2,"col":1,"index":1},{"row":3,"col":1,"index":2}]
9:31:51 AM Notice Execution completed
Sheet1:
COL1
good
bad
ugly

My input-function in javascript always return false, even when a user inputs the correct value

I want to know why my function always returns false, and how I can fix it.
At first I thought it had something to do with my syntax at check = ("stairway to heaven"===value || "Stairway to heaven"===value);. But no matter how I put it, it's always false.
I tried reading into this, but as far as I could understand, it doesn't help me.
I've created this in JavaScript to do different things depending on if the result of check is true or false.
else if (textNodes[15].id === 16 && nextTextNodeId === 16) {
showSongContainer();
if(check) {
showTextNode(17);
}
if (!check) {
textElement.innerText = 'That’s superwrong! Maybe if you would use that small brain of yours you’d figure it out!';
showTextNode(11);
}
The above code runs this function first, to determine if a text input returns true (stairway to heaven) or false (anything other than stairway to heaven):
function showSongContainer() {
songContainer.style.display = 'unset';
const songInput = document.getElementById('songInput');
const songButton = document.getElementById('songButton');
songButton.addEventListener('click', (e) => {
e.preventDefault();
let value = songInput.value;
check = ("stairway to heaven"===value || "Stairway to heaven"===value);
});
}
However, when the first else ifstarts (in the first codeblock), it always goes to the if(!check), before the text input has even been entered. Why is this? And how do I make it so that it returns the first if (in the first code block) if the text input is correct, and the other if, if incorrect?
I also have let check = ''; in a global scope at the beginning of my code, if that has anything to do with it.

When I turn document.cookie into an array, and then use conditional statement with indexof, it works only for the first value. Why?

It's hard to even describe the question. I can't reproduce a snippet, obviously because it requires using cookies, but I will try to reproduce it with a normal array, and show you how it should work, then I'll show you screenshots of my code, and the outcome it produces when used on real cookies.
function cookiename(name) {
//var test5 = document.cookie.split(";");
var test5 = ["user=Jim Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
var username2 = name;
var output = "";
if(test5[0].indexOf("user") == 0) {
output = test5[0].substring(username2.length, test5[0].length);
} else alert("IT DOES NOT WORK");
alert(output);
}
cookiename("user");
This is pretty much what my code looks like, except that, instead of array, test5 is assigned to document.cookie.split(";"), and it contains two more cookies.
Now, the way it works is, you create a conditional statement with the array value, in this case, test5[0], which contains the value "user=Jim Jordan", and say, if the indexof("user") string is in position 0 inside the test5[0] string, which contains the value user=Jim Jordan, then execute the condition, if not, alert that it doesn't work.
Now, as you saw, it works great in the above example. It works as expected with any of the other array values. test5[1], test5[2] etc. will work the same way, of course in the above example they won't match the condition, but if you change the indexof string, it works.
Now, the issue I have is that, the test5 variable stores the document.cookie.split(";") array, and only the first array value works, while the others don't, even though the condition should be matching. However, the other values do work but only if the indexof string is intentionally wrong, and doesn't exist inside the array value, and the condition is of course -1. If the indexof string actually exists, both 0 and -1 conditions don't match. Very strange.
Here's a screenshot of my code, and subsequent result:
First array value
So, as you can see, the first value works as expected.
But then, when I try with another array value, it doesn't work. The third array value is called username=Sam Jones. This is what happens when I change indexof("user") with indexof("username").
Third array value
As you can see, the prior alert that I inserted displays that test5[2] contains the value of username=Sam Jones, but then when use it as a condition, the indexof("username") does not match it. It should be 0, but it's not. Even when I try -1, instead of 0, which matches strings that do not exist, it still produces the exact same outcome! Why!?
Now, watch what happens when I add a string in indexof that does not exist. Instead of the string username, I will add something random, and use -1 as a condition.
Different indexof string on Third array value
As you see, now the random indexof string matches the -1, because it doesn't exist. But why when the indexof string actually does exist, neither 0 nor -1 match the condition?
Why only the first array value work?
Does anyone have any idea what is happening here?
Your approach is flawed since you are expecting that the cookie will always be in the same order. You are also checking for the start of a string equals. When you have user, it will also match username. You are not accounting for the = and you are not removing the encoding.
So to do it with your approach with indexOf and substring, you would need to loop over and check that it has a match
function getCookie(key) {
// var myCookies = document.cookie.split(/;\s?/g);
var myCookies = ["user=Jim%20Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
for (var i = 0; i < myCookies.length; i++) {
var current = myCookies[i];
if (current.indexOf(key + "=") === 0) {
return decodeURIComponent(current.substr(key.length+1));
}
}
}
console.log('user', getCookie('user'));
console.log('username', getCookie('username'));
console.log('funky', getCookie('funky'));
Most approaches would use a regular expression.
function getCookie(key) {
// var myCookies = document.cookie;
var myCookies = "user=Jim%20Jordan;color=blue;cat=bella;username=NikoaTesla";
var cookieValue = myCookies.match(`(?:(?:^|.*; *)${key} *= *([^;]*).*$)|^.*$`)[1]
return cookieValue ? decodeURIComponent(cookieValue) : null;
}
console.log('user', getCookie('user'));
console.log('username', getCookie('username'));
console.log('funky', getCookie('funky'));
If I have to read multiple values I would map it to an object
function getCookieValues() {
// var myCookies = document.cookie.split(/;\s?/g);
var myCookies = ["user=Jim%20Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
return myCookies.reduce(function (obj, item) {
var parts = item.split("=");
obj[parts[0]] = decodeURIComponent(parts[1]);
return obj;
}, {});
}
var myCookies = getCookieValues();
console.log('user', myCookies['user']);
console.log('username', myCookies['username']);
console.log('funky', myCookies['funky']);
What you want is to find cookies starting with name, correct?
Firstly, you are probably aware, but it is good to note that if your cookies come this way: cookies = "user=Jim Jordan; color=blue; cat=bella; username=NikoaTesla";, you have to split for "; " instead of just ";".
Once your splits are correct, already without any leading spaces, you only need:
test5.filter(c=>c.trim().startsWith("user"));
I believe startsWith is cleaner than using indexOf.
Another solution, without split:
For the "; " case:
const cookiestr='; '+cookies+';';
while (true) { i=cookiestr.indexOf('; user',i+1); if (i<0) break; console.log(cookiestr.substring(i+2,cookiestr.indexOf(';',i+1))); }
For the ";" case:
const cookiestr=';'+cookies+';';
while (true) { i=cookiestr.indexOf(';user',i+1); if (i<0) break; console.log(cookiestr.substring(i+1,cookiestr.indexOf(';',i+1))); }
In your conditional, test5[2] = “cat=bella”, not “username=NikolaTesla”. That’s at index 3. Could try that?
Also check for white spaces being being added to the front of end of each string like someone mentioned already.

How to find JSON string in HTML file

I'm trying to find a plaintext JSON within a webpage, using Javascript. The JSON will appear as plaintext as seen in the browser, but it is possible that it would be truncated into separate html tags. Example:
<div>
{"kty":"RSA","e":"AQAB","n":"mZT_XuM9Lwn0j7O_YNWN_f7S_J6sLxcQuWsRVBlAM3_5S5aD0yWGV78B-Gti2MrqWwuAhb_6SkBlOvEF8-UCHR_rgZhVR1qbrxvQLE_zpamGJbFU_c1Vm8hEAvMt9ZltEGFS22BHBW079ebWI3PoDdS-DJvjjtszFdnkIZpn4oav9fzz0
</div>
<div>
xIaaxp6-qQFjKXCboun5pto59eJnn-bJl1D3LloCw7rSEYQr1x5mxhIxAFVVsNGuE9fjk0ueTDcMUbFLPYn6PopDMuN0T1B2D1Y8ClItEVbVDFb-mRPz8THJ_gexJ8C20n8m-pBlpL4WyyPuY2ScDugmfG7UnBGrDmS5w"}
</div>
I've tried to use this RegEx.
{"?\w+"?:[^}<]+(?:(?:(?:<\/[^>]+>)[^}<]*(?:<[^>]+>)+)*[^}<]*)*}
But the problem is it fails to work with nested JSON.
I may also use javascript to count the number of { and } to find where the JSON actually ends, but there must be better options than using this slow and clumsy approach.
Many thanks
Update:
Perhaps there ain't better way to do this. Below is my current code (a bit verbose but probably needed):
let regex = /{[\s\n]*"\w+"[\s\n]*:/g;
// Consider both open and close curly brackets
let brackets = /[{}]/g;
let arr0, arr;
// Try to parse every matching JSON
arr0 = match.exec(body);
if (arr0 === null) { // Nothing found
return new Promise(resolve => resolve());
}
try {
brackets.lastIndex = match.lastIndex; // After beginning of current JSON
let count = 1;
// Count for { and } to find the end of JSON.
while ((count !== 0) && ((arr = brackets.exec(body)) !== null)) {
count += (arr[0] === "{" ? 1 : -1);
}
// If nothing special, complete JSON found when count === 0;
let lastIdx = brackets.lastIndex;
let json = body.substring(match.lastIndex - arr0[0].length, lastIdx);
try {
let parsed = JSON.parse(json);
// Process the JSON here to get the original message
} catch (error) {
console.log(err);
}
...
} catch(err) {
console.log(err);
};
That's not possible in a good way, it might be possible to take a parent element's innerText and parse that:
console.log(JSON.parse(document.getElementById('outer').innerText.replace(/\s|\n/g, '')));
<div id="outer">
<div>
{"kty":"RSA","e":"AQAB","n":"mZT_XuM9Lwn0j7O_YNWN_f7S_J6sLxcQuWsRVBlAM3_5S5aD0yWGV78B-Gti2MrqWwuAhb_6SkBlOvEF8-UCHR_rgZhVR1qbrxvQLE_zpamGJbFU_c1Vm8hEAvMt9ZltEGFS22BHBW079ebWI3PoDdS-DJvjjtszFdnkIZpn4oav9fzz0
</div>
<div>
xIaaxp6-qQFjKXCboun5pto59eJnn-bJl1D3LloCw7rSEYQr1x5mxhIxAFVVsNGuE9fjk0ueTDcMUbFLPYn6PopDMuN0T1B2D1Y8ClItEVbVDFb-mRPz8THJ_gexJ8C20n8m-pBlpL4WyyPuY2ScDugmfG7UnBGrDmS5w"}
</div>
</div>
But it's likely to fail sometimes

How to check if condition if property has a string?

How to check with if condition if response has a string , if response has a string then execute the if condition.basically if there is error from server i want to make $scope.ActiveFile true.
main.js
$scope.onError = function(e) {
console.log('Error while uploading attachment', e.XMLHttpRequest.response);
$scope.errorMessage = JSON.parse(e.XMLHttpRequest.response).techErrorMsg;
if ($scope.errorMessage >= 1){
$scope.applyActiveFile = true;
}
};
response.json
Server response: {"errorCode":500,"errorMsg":"Service failed. Please contact administrator.","techErrorMsg":"Sheet : PROCESS_INVENTORY not found in the File"}
To solve your specific query this should work
if ($scope.errorMessage != null/blank) //whatever suits you
{
$scope.applyActiveFile = true;
}
Now answering what your question heading says - to check if property is string
if (typeof response === string)
/*typeof tells the type of operator, it will return number in case of number and string in case of string*/
{
$scope.applyActiveFile = true;
}
As mic4ael said, you could use some condition such as:
if ($scope.errorMessage)
$scope.applyActiveFile = true;
You could use some regular expression such as:
if ((/^\s*$/).test($scope.errorMessage))
$scope.applyActiveFile = false;
...which would check if the string is empty or has only white spaces and turn your trigger to false. You'd only want to check one or two values with this, though cause it'll be performance-heavy otherwise.
Many other solutions...
Something like this
for (var i in $scope.errorMessages){
if (typeof $scope.errorMessages[i] === "string"){
alert($scope.errorMessages[i]);
}
}
To test in browser console input:
var a = {"errorCode":500,"errorMsg":"Service failed. Please contact administrator.","techErrorMsg":"Sheet : PROCESS_INVENTORY not found in the File","thirdFieldNotString":1};
for (var i in a){
if (typeof a[i] === "string"){
alert('Value is string');
}
};

Categories