Is it possible to use .reduce with a const? - javascript

I was completing an assignment in my coding bootcamp. They asked us to use .reduce to come up with a value. However, they initialized the total value using a const variable. When I would try to solve this problem using the const value, it kept throwing errors.
Because in my head, you can't change the const value. I simply replaced const with let. I'm not sure if I was supposed to change the code in that way but that's what I did.
const populationTotal = 0;
populationTotal = zooAnimals.reduce((total, item) => total + item.population, 0);
console.log(populationTotal);
If I keep the code the way it is, (const populationTotal = 0), it throws an error. When I changed the code (let populationTotal = 0), the problem was solved. Am I correct in thinking that you have to change const to let. Or is there a way to solve this problem with a const initial value?

Am I correct in thinking that you have to change const to let.
Yes, if you want to mutate the variables value after declaration.
Or is there a way to solve this problem with a const initial value
Sure. You can choose another initial value instead of 0.
const populationTotal = /* calculate the result here */;

Related

Function changes the value of parameter unexpectedly

I wrote a function calcNewtonPath with 4 parameters as below. However when i call it, the function changes the value of parameter matA unexpectedly and i can't understand why.
function calcNewtonPath(matA,matB,m,n){
let temp = matA.slice() //i tried this to prevent the unexpected change but it didn't work
for(let i=0;i<m;i++){
temp[i].push(-matB[i])
}
return matrix.solve(temp,m,n)
}
The function solve also changes the value of temp too! But it's a bit complicated so i think i will not put the code here.
Can anyone help me about this?
UPDATED:
.slice() will just do a shallow copy.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
That means for example:
const a = [[1,2,3]]
const b = slice.a();
b[0][1] = 4;
a array will also be changed.
a will be [[1,4,3]] as well as b;
One easy solution would be to make a deep copy of an array:
const deepCopy = JSON.parse(JSON.stringify(array));

Modify and write an input html value in javascript

I'm working on a fronted calculator project but i don't really understand a strange behavior in Javascript.
This is my script:
const keys = document.querySelectorAll(".number");
const screen = document.querySelector("#screen");
let number = screen.value;
keys.forEach((key) => {
key.addEventListener("click", (event) => {
let refresh = (number += key.textContent).toString();
console.log(number);
screen.value = refresh;
});
});
Someone can tell me why if i change this line
screen.value = refresh;
with this one
number = refresh;
my value on the screen does not update despite in my console it is updating?
Aren`t these two different names to call the same thing?
Thank you
This is caused by string variables being assigned a value instead of a reference. This means that when you call let number = screen.value it only sets number to the value screen.value has at that moment. But if you change one of them, the other remains the same.
This is true for primitive types like numbers, strings and booleans. Objects and array variables are assigned references, meaning that changing the object through one variable will be reflected in all other variables pointing to the same object.
This is because you are using this line:
console.log(number);
So you will first print 'number' variable and later you will update the value of this variable, so this is the problem
if you want to solve this you have to invert the order of the lines something like this:
screen.value = refresh;
console.log(number);
I hope I've helped ;)

What's the drawback of `let count = useRef(0).current`

Example Code:
(Pretend we are inside component function)
let count = useRef(0).current
useEffect(()=>{
count++
console.log(count)
}, [count])
Question:
What will happen if I run this code
(I am afraid that the endless loop execution will blow up my m1 chip macbookair, so I didn't run ^_^).
Should I awalys some_ref_object.curent = some_value to change the value?
The code probably will not do what you expect.
useRef returns a mutable object, where the object is shared across renders. But if you extract a property from that object into a variable and then reassign that variable, the object won't change.
For the same reason, reassigning the number below doesn't change the object:
const obj = { foo: 3 };
let { foo } = obj;
foo = 10;
console.log(obj);
In your code, the ref object never gets mutated. It is always the following object:
{ current: 0 }
So
let count = useRef(0).current
results in count being initially assigned to 0 at the beginning of every render.
This might be useful if for some odd reason you wanted to keep track of a number inside a given render, not to persist for any other render - but in such a case, it'd make a lot more sense to remove the ref entirely and just do
let count = 0;
Your effect hook won't do anything useful either - since count is always 0 at the start of every render, the effect callback will never run (except on the first render).
Should I awalys some_ref_object.curent = some_value to change the value
You should use current, not curent. But yes - if you want the change to persist, assign to a property of the object, instead of reassigning a standalone variable. (Reassigning a standalone variable will almost never have any side-effects.)
But, if you have something in the view that the count is used in - for example, if you want to return it in the JSX somewhere - you probably want state instead of a ref (or a let count = 0;), so that setting state results in the component re-rendering and the view updating.
I just tried it on my colleague's computer, and fortunately it didn't blow up
Conclusion 1:
The useEffect won't effect, because ref can't be denpendency.
Conclusion 2:
Only let count = useRef(0).current is the right way.

When assigning the result of an addition to a variable, calculator doesn't work. Why?

I'm experimenting with my very basic Javascript and I found a nice Tutorial on how to make a very basic calculator in JS.
I tried following along with the video but I didn't want to just "copy-paste" what he was writing so I stopped and tried to do what I thought was the logic code...WRONG!
Here the problem
Why this doesn't work?
function addNum() {
let first = document.querySelector('.first').value;
let second = document.querySelector('.second').value;
let result = document.querySelector('.resultt').value;
return result = first + second
}
I tried to assign the input related to the result to a variable but it doesn't work.
But when I do this: (as it was done in the tutorial)
function addNum() {
let first = parseInt(document.querySelector('.first').value);
let second = parseInt(document.querySelector('.second').value);
document.querySelector('.resultt').value=first + second;
}
So without assigning the result to a variable, it works.
Why?
When you do
let result = document.querySelector('.resultt').value;
you're copying the value from the value property to the result variable. There's no ongoing link between them after that, they each just contain the same string. That means later, when you do result = first + second, all you're doing is updating result; that has no effect at all on value.
So you have to assign back to value as you do in your second code block.

Defining variable as let and var showing NaN

I am using a variable like below :
var maxId=1;
schema.table.max('id').then(function(max) {
maxId=max+1;
}).catch(err => {
maxId=1;
});
to take the maximum id from the DB and add one.
console.log(maxId) //prints the maximum id.
I also want to add the new id for the new data by below :
schema.table.findAll({where: option}).then((existed) => {
for (let insert of insertionList) {
insert['id'] = maxId;
maxId=maxId+1;
}
})
Here insertionList's id attribute is showing as NaN instead of the max .
I used let and var but both resulted in NaN. Any help is appreciated.
This is a generic answer, not only based on what you wrote.
It will help you to debug your problem and write more concise code.
Declaring a variable somewhere and change it within a promise is a very bad practice, you can create something unpredictable and it can be based on race conditions.
Your variable at the time you read it can be easily undefined or something. It's all based on timing.
Something like:
var maxId=1;
schema.table.max('id').then(function(max) {
maxId=max+1;
}).catch(err => {
maxId=1;
});
can be easily translated to:
const maxId = await schema.table.max('id')
.then(max => {
// here some checks on max (can it be null or undefined?)
return max + 1;
}, () => 1);
To avoid side effects try to use "const" as much as you can instead of "let" and "var". If you are forced to use let or var in most of cases means you are doing it wrong especially when you use promises or async code.
An important consideration....
What you wrote implies that an error would consider max == 1. Throwing an error (or reject a promise) should be handled in a proper way (and not like your example, not even like in mine...). The library you use probably would reject your promise in case of an I/O issue or a lack of permission. Those cases shouldn't imply max = 1 but they should be reported in order to take additional actions.
undefined + 1
=> NaN
I think that when your db is empty, it wont pass by your catch statement because there had been no error trying to get the max value (even if it is undefined).
You should handle the case of max being undefined.
Here is my solution written in ES6:
let maxId = 1;
schema.table.max('id')
.then(max => maxId = (max || 0) + 1)

Categories