Reputation: 127
class Discount {
discount;
constructor() {
this.key = '';
this.code = '';
this.discountValue = 0;
}
checkData(searchCode) {
fetch('discount.json').then ((response) =>{
return response.json()
}).then ((obj)=>{
Object.keys(obj).forEach(function(key) {
obj[key].forEach((data)=> {
// console.log(data.code);
// console.log(obj[key]);
if (data.code === searchCode) {
console.log(key);
console.log(data.code);
console.log(data.discount);
this.key = key;
this.code = data.code;
this.discountValue = data.discount;
}
});
});
console.log(this.key);
console.log(this.code);
console.log(this.discountValue);
}).catch((error)=>{
console.error('Wrong');
console.error(error);
});
}
}
document.addEventListener("DOMContentLoaded", () =>{
document.getElementById('calcDiscount').addEventListener('click', ()=>{
const codeInput = document.getElementById('codeInput').value.toUpperCase();
const myName = new Discount();
myName.checkData(codeInput);
});
});
at main.js:20
at Array.forEach (<anonymous>)
at main.js:13
at Array.forEach (<anonymous>)
at main.js:12
(anonymous) @ main.js:34
Promise.catch (async)
checkData @ main.js:32
(anonymous) @ main.js:47
Why this code does not work? please help me, i can't understand. Please explain to me the solution of this problem if you know how. It's a discount, taking data from the json, it should return key, code and the value, but does not work.
Upvotes: 0
Views: 845
Reputation: 7901
this
inside the forEach
loop i:e this.key = key
, is not pointing to the Discount
class instance.
The normal function as callback will create it's own this
i:e Object.keys(obj).forEach(function(key) {
Instead use arrow based function, which do not have it's own this
and will refer to the this
from the outer immediate scope, which is pointing to the class instance.
Object.keys(obj).forEach(() => (key) {
.
checkData(searchCode) {
// here `this` points to the class instance
fetch('discount.json').then ((response) =>{
// this is retrieved from the outer scope, which is class instance
return response.json()
}).then ((obj)=>{
// this is retrieved from the outer scope, which is class instance
Object.keys(obj).forEach(function(key) {
// The normal callback function, will create it's own this, so `this` won't point to the class instance.
obj[key].forEach((data)=> {
// Here, this refer to newly created `this` from the immediate enclosed function.
if (data.code === searchCode) {
console.log(key);
console.log(data.code);
console.log(data.discount);
this.key = key;
this.code = data.code;
this.discountValue = data.discount;
}
});
});
Upvotes: 1
Reputation: 1767
Try this below :
You need to use async await since the call is asynchrounous , the execution doesnt wait for your response and thats why you are getting undefined in your Object.keys(obj)
async checkData(searchCode) {
await fetch('discount.json').then ((response) =>{
return await response.json()
}).then ((obj)=>{
Object.keys(obj).forEach(function(key) {
obj[key].forEach((data)=> {
// console.log(data.code);
// console.log(obj[key]);
if (data.code === searchCode) {
console.log(key);
console.log(data.code);
console.log(data.discount);
this.key = key;
this.code = data.code;
this.discountValue = data.discount;
}
});
});
console.log(this.key);
console.log(this.code);
console.log(this.discountValue);
}).catch((error)=>{
console.error('Wrong');
console.error(error);
});
}
Upvotes: 0
Reputation: 2312
Try Using ES6 arrow functions.
class Discount {
discount;
constructor() {
this.key = '';
this.code = '';
this.discountValue = 0;
}
checkData = (searchCode) => {
fetch('discount.json').then (res=>res.json()).then ((obj)=>{
Object.keys(obj).forEach((key) => {
obj[key].forEach((data)=> {
// console.log(data.code);
// console.log(obj[key]);
if (data.code === searchCode) {
console.log(key);
console.log(data.code);
console.log(data.discount);
this.key = key;
this.code = data.code;
this.discountValue = data.discount;
})
});
});
console.log(this.key);
console.log(this.code);
console.log(this.discountValue);
}).catch((error)=>{
console.error('Wrong');
console.error(error);
});
}
}
Upvotes: 0