Reputation: 23
I have little experience with JS and I'm following a video course on React. Most things makes sense but I'm having some trouble with reference scopes.
Here's what the tutor writes:
const orderIds = Object.keys(this.props.order);
const total = orderIds.reduce((prevTotal, key) => {
const fish = this.props.fishes[key];
const count = this.props.order[key];
const isAvailable = fish && fish.status === 'available';
if (isAvailable === true) {
return prevTotal + count * fish.price;
} else {
return prevTotal;
}
}, 0);
He is using an arrow-function. It works of course.
I want to do the same but with writing a "normal" function, because for now I don't want to make any shortcuts:
const orderIds = Object.keys(this.props.order);
const total = orderIds.reduce(
function(prevTotal, key) {
const fish = this.props.fishes[key];
const count = this.props.order[key];
const isAvailable = fish && fish.status === 'available';
if (isAvailable === true) {
return prevTotal + (count * fish.price);
} else {
return prevTotal;
}
}
, 0);
The problem is:
TypeError: this is undefined
So there's a problem with the scope of the reference to this.props...
I got this to work within a .map()-function by passing it a second argument of
... , this)
from searching online about referencing this.
That doesn't work for the reduce()-function. So, what can one do in my situation? Again, I don't want to use the shorter arrow-function because it's like a shortcut I don't want to use when learning. I've searched online about scopes on this and also about the reduce()-function but the examples I've seen doesn't quite fit what I'm looking for, or I'm simply not savvy enough to use what they're writing.
Thanks a ton if you can help me out, regards / HW
Upvotes: 2
Views: 189
Reputation: 556
You can use bind as suggest upper or rewrite code like this:
const orderIds = Object.keys(this.props.order);
const { fishes, order } = this.props;
const total = orderIds.reduce(
function(total, key) {
const fish = fishes[key];
const count = order[key];
const isAvailable = fish && fish.status === 'available';
if (!isAvailable) return total;
return total + (count * fish.price);
}
, 0);
Upvotes: 0
Reputation: 22885
Arrow functions has parent scope so this represents parent's this
but simple function don't. You can tell the function about this using .bind(this)
const total = orderIds.reduce(
(function(prevTotal, key) {
const fish = this.props.fishes[key];
const count = this.props.order[key];
const isAvailable = fish && fish.status === 'available';
if (isAvailable === true) {
return prevTotal + (count * fish.price);
} else {
return prevTotal;
}
}).bind(this)
, 0);
Upvotes: 1