I can't figure out where I made a mistake in the syntax, please help. The error is in the first line. I made everything else before I did the first line and the error wasn't there before I made it.
String msg.payload2 = msg.payload.toLowerCase();
if (msg.payload2 == "-coinflip") {
rnd = Math.floor (Math.random() * (2-0));
if (rnd == 1) {
msg.payload = "Heads";
} else {
msg.payload = "Tails";
}
}
return msg.payload
msg is already an object therefore you can add properties without further declaration. And there is no need to cast a variable to anything in JS.
Your code should be:
msg.payload2 = msg.payload.toLowerCase();
if (msg.payload2 == "-coinflip") {
rnd = Math.floor (Math.random() * (2-0));
if (rnd == 1) {
msg.payload = "Heads";
} else {
msg.payload = "Tails";
}
}
return msg.payload
JavaScript is loosely typed. When accessing a property on an object, using the syntax msg.payload2 you should receive the value contained in the property payload2 from the msg object. However, if the property doesn't exist, the payload2 property will return undefined. This is why your code worked before adding the first line in your example.
This line:
if (msg.payload2 == "-coinflip")
will always evaluate to false if the payload2 property is never defined.
The reason it didn't work when you added line 1 of your code snippet in; is that you're trying to give a type to an object property in JavaScript using syntax that the JS engine doesn't understand and will throw a SyntaxError.
EDIT:
let msg = { payload: '' }; // assuming this is an object defined higher up. I've placed this here for more context
let result;
msg.payload2 = msg.payload && msg.payload.toLowerCase(); // This line also protects against trying to lowercase an undefined payload
if (msg.payload2 == "-coinflip") {
rnd = Math.floor (Math.random() * (2-0));
if (rnd == 1) {
result = "Heads";
} else {
result = "Tails";
}
}
return result;
I don't consider this production code but it will get your app running.
Related
I have a props of folllowing form :
type Props = {
row = ?number
};
When I try to do
if (row === null) {
return null;
}
const percent = Math.round((row * 100)/20);
I get error that
operand of an arithmetic operation must be a number
If I do
type Props = {
row = number
};
error goes away.
Any suggestions on what to do :)
If this code is not in a function.
Here even if your row is null you are executing your second statement. Put it in else part. And you also need to return percent.
Like this-
if (row === null) {
return null;
}
else {
const percent = Math.round((row * 100)/20);
return percent;
}
I'm trying to write a function that takes in an array as an input. If the integer is positive, it counts it. If the integer is negative, it sums it.
I figured that that the reduce() helper in js would be the best way to go about this, but I keep returning undefined for my first argument when it runs.
Here's my code:
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0
if (input === null || input === []){
return [];
} else {
return input.reduce(function(prev,num){
if (num > 0) {
countPositive++;
}else{
sumNegative = prev + num};
}, 0);
}
return [countPositive, sumNegative];
}
It throws me a TypeError that says:
TypeError: Cannot read property '0' of undefined
When I log 'prev' to the console inside of the reduce function, it logs undefined for all inputs except the first one. The first one, as expected, is 0. But for each following input it logs undefined. Why is this happening?
Thanks in advance.
The callback you pass to .reduce() needs to return the cumulative value (the value that will be passed as prev to the next iteration of the loop. Since you are returning nothing, you get undefined for the next iteration of your loop.
This complicates what you're trying to do because you are trying to keep track of two values in your loop. As such, you would either have to avoid using prev at all or you'd have to make it be a data structure that had both your values in it. Your use is not a textbook example for .reduce(). Your code is probably simpler with an iteration using .forEach() or for/of.
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0
if (!input || input.length === 0){
return [];
} else {
input.forEach(function(num){
if (num > 0) {
++countPositive;
} else {
sumNegative += num;
});
}
return [countPositive, sumNegative];
}
Well sorry but this is not a good implementation of this function. But we can correct your function as follows;
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0;
if (input === null || input === []){
return [];
} else {
sumNegative = input.reduce(function(prev,num){
if (num > 0) {
countPositive++;
} else {
prev += num;
}
return prev; // <---- THE MISSING PART
}, 0);
}
return [countPositive, sumNegative];
}
var data = [1,2,3,4,5,-4,7,-3];
console.log(countPositivesSumNegatives(data));
However while the code works just fine it still involves many issues. When getting into functors like .reduce() you should be able to keep everthing contained within itself and should not refer to variables at the outer scope. Accordingly one can simply rephrase this code as follows;
var data = [1,2,3,4,5,-4,7,-3],
cpsn = a => a.reduce((p,c) => c > 0 ? (p[0]++,p) : (p[1]+=c,p) ,[0,0]);
console.log(cpsn(data))
apologies for the stupid question. I am trying to solve this Kata on Codewars, https://www.codewars.com/kata/the-enigma-machine-part-1-the-plugboard/train/javascript/. Its basically the beginnings of an Enigma machine. I feel like I made some good progess on it. Now I'm running it through pythontutor.com but I cannot for the life of me figure out why when I run this, the second iteration of the for loop changes the property 'A' of Plugboard into 'C' and does not create a new property 'C' with value of 'A'. I am sure this is a simple concept that I am completely missing, but I sure would appreciate any insight into this.
class Plugboard {
constructor(wires) {
if(wires.length % 2 !== 0 || wires.length === 0 || wires.length > 20){
throw 'Error'
}
console.log(wires)
this.str = wires.split('')
for(var i = 0; i < this.str.length; i += 2){
if(this.hasOwnProperty(this.str[i])){
throw 'Duplicate';
}
this[this.str[i+1]] = this.str[i];
this[this.str[i]] = this.str[i+1];
}
}
process(chr){
if(!this.hasOwnProperty(chr)){
return chr
} else {
return this[chr];
}
}
}
var plugboard = new Plugboard("ABCA");
The C property does exist and has a value of "A". I ran it on repl.it, and it just works...
class Plugboard {
constructor(wires) {
if(wires.length % 2 !== 0 || wires.length === 0 || wires.length > 20){
throw 'Error'
}
console.log(wires)
this.str = wires.split('')
for(var i = 0; i < this.str.length; i += 2){
if(this.hasOwnProperty(this.str[i])){
throw 'Duplicate';
}
this[this.str[i+1]] = this.str[i];
this[this.str[i]] = this.str[i+1];
}
}
process(chr){
if(!this.hasOwnProperty(chr)){
return chr
} else {
return this[chr];
}
}
}
var plugboard = new Plugboard("ABCA");
console.log(plugboard);
console.log("Value of C:",plugboard.C);
console.log("Value of A:",plugboard.A);
console.log("Value of B:",plugboard.B);
repl.it link: https://repl.it/GJg7/2
I am guessing that you may have got the wording wrong in the question, and are actually worried about the A property containing the C value, not the reverse.
On the first loop we make the following assignments:
this["B"] = "A"
this["A"] = "B"
On the second loop we make the following assignments:
this["A"] = "C"
this["C"] = "A"
Note that this overwrites the existing value of this["A"]. It is not detected as a duplicate, because we only check this.str[i] and do not check if this.str[i+1] is a duplicate. It does not add a duplicate property, because we cannot have a duplicate property. It does exactly what it is told to do.
If this is not the desired behaviour, what is the desired behaviour?
Thank you all for your input. I realised my mistake, I was overriding the property C on my second pass. Issue solved, thanks and sorry for my ignorance
I have an array and I want to get the minimum of all stardates and maximum of all end dates.
I am sorting the array first and then getting min and max of it.
Below is the code.
var ticket_arr = '[{"Id":"a874062a-3f1e-4f91-a9d7-334aedd2e79f","Name":"Tesr","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"19f3722f-5f19-430a-bf8a-699c6841aec2","Name":"Go define this test projecct","StartDate":"2015-04-21","EndDate":"2015-04-29","Duration":"8","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5576edbf-3feb-4204-b488-0d0a35688538","Name":"Mike is getting a lesson in cool","StartDate":"2015-04-08","EndDate":"2015-04-10","Duration":"2","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5bf5d77c-73b1-480b-8758-2e822db73964","Name":"Test ticket","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false}]';
function sortArray(arr, name){
arr.sort(function(a,b)
{
if (new Date(a[name]) > new Date(b[name]) )
return 1;
else if (new Date(a[name]) < new Date(b[name]) )
return -1;
else
return 0;
});
}
function getMinMaxDate(arr, name, type)
{
if(arr.length)
{
sortArray(arr, name);
console.log(arr);
console.log(name);
if(type == "Min" && arr.length)
{
console.log(arr[0][name]);
return arr[0][name];
}
if(type == "Max" && arr.length)
{
return arr[arr.length-1][name];
}
}
else
return '';
}
But the code gives an error that says arr.sort is not a function.
That's because ticket_arr isn't an array, it's a string. Fix that either by removing the single quotes around the value:
var ticket_arr = [{"Id":"a874062a-3f1e-4f91-a9d7-334aedd2e79f","Name":"Tesr","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"19f3722f-5f19-430a-bf8a-699c6841aec2","Name":"Go define this test projecct","StartDate":"2015-04-21","EndDate":"2015-04-29","Duration":"8","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5576edbf-3feb-4204-b488-0d0a35688538","Name":"Mike is getting a lesson in cool","StartDate":"2015-04-08","EndDate":"2015-04-10","Duration":"2","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5bf5d77c-73b1-480b-8758-2e822db73964","Name":"Test ticket","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false}];
Or, if it's loaded via AJAX or generated on the client side, by parsing it as JSON:
var ticket_arr = JSON.parse('[{"Id":"a874062a-3f1e-4f91-a9d7-334aedd2e79f","Name":"Tesr","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"19f3722f-5f19-430a-bf8a-699c6841aec2","Name":"Go define this test projecct","StartDate":"2015-04-21","EndDate":"2015-04-29","Duration":"8","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5576edbf-3feb-4204-b488-0d0a35688538","Name":"Mike is getting a lesson in cool","StartDate":"2015-04-08","EndDate":"2015-04-10","Duration":"2","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false},{"Id":"5bf5d77c-73b1-480b-8758-2e822db73964","Name":"Test ticket","StartDate":"2015-04-08","EndDate":"2015-04-09","Duration":"1","leaf":true,"IsProject":false,"IsStage":false,"IsActivity":false,"IsTicket":true,"IsTask":false}]');
(If you intend to use JSON.parse on older browsers, such as IE7-, you'll need a polyfill. JSON 3 is a well-known one.)
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.