Reputation: 619
I'm working in a JS class and I can't figure out the reason why colors.ColorCheck(0).ColorCode
and colors.ColorCheck(0).Color
return undefined
values.
As you can see, "0" is passed as an argument of the function ColorCheck
and is used inside the functions this.ColorCode
and this.Color
.
I'm pretty sure I'm missing something in declaring the two functions (this.ColorCode
and this.Color
) inside the main function (ColorCheck
), but I can't see what.
I'm a newbie in JS, so I wouldn't be surprised if the solution seems evident for you guys.
class Colors {
constructor(){}
async ColorCheck(ID){
this.ColorCode = (async()=>{
this.info = await axios.get ('https://.../${ID}.json')
this.CodeC = this.info.map(t=>t.colorcode)
return this.CodeC
})
this.Color = (async()=>{
this.info = await axios.get ('https://.../${ID}.json')
this.C = this.info.map(t=>t.color)
return this.C
})
}
}
const colors = new Colors()
colors.ColorCheck(0).ColorCode
colors.ColorCheck(0).Color
Upvotes: 1
Views: 879
Reputation: 21171
Your ColorCheck
function is not returning anything, so when calling it as colors.ColorCheck(0)
, that's returning undefined
.
I think rather than setting this.ColorCode
and this.Color
, with this
referring to the Color
instance, what you actually want is to return an object with two keys, ColorCode
and Color
, whose values are two curried async functions that will make a GET
request with the provided id
when called.
That would probably look something like this:
// Just mocking axios for this example:
const axios = {
get: (url) => new Promise((resolve, reject) => {
console.log(`Making a request to ${ url }...`);
setTimeout(() => {
resolve([{
colorCode: '#F00',
color: 'red',
}, {
colorCode: '#0F0',
color: 'green',
}, {
colorCode: '#00F',
color: 'blue',
}]);
}, 2000);
}),
};
class Colors {
constructor() { }
ColorCode(id) {
return {
ColorCode: (async () => {
const info = await axios.get(`https://.../${ id }.json`);
return info.map(t => t.colorCode);
}),
Color: (async () => {
const info = await axios.get(`https://.../${ id }.json`);
return info.map(t => t.color);
}),
};
}
}
const colors = new Colors();
const returnedValue = colors.ColorCode(0);
(async () => {
console.log((await returnedValue.ColorCode()).join(', '));
console.log((await returnedValue.Color()).join(', '));
})();
.as-console-wrapper {
max-height: none !important;
}
You could also move the axios call to the ColorCode
function (without making it async
) so that you don't make an additional request every time any of the two returned functions are called:
// Just mocking axios for this example:
const axios = {
get: (url) => new Promise((resolve, reject) => {
console.log(`Making a request to ${ url }...`);
setTimeout(() => {
resolve([{
colorCode: '#F00',
color: 'red',
}, {
colorCode: '#0F0',
color: 'green',
}, {
colorCode: '#00F',
color: 'blue',
}]);
}, 2000);
}),
};
class Colors {
constructor() { }
ColorCode(id) {
// Note there no `await` here:
const infoPromise = axios.get(`https://.../${ id }.json`);
return {
ColorCode: (async () => {
return (await infoPromise).map(t => t.colorCode);
}),
Color: (async () => {
return (await infoPromise).map(t => t.color);
}),
};
}
}
const colors = new Colors();
const returnedValue = colors.ColorCode(0);
(async () => {
console.log((await returnedValue.ColorCode()).join(', '));
console.log((await returnedValue.Color()).join(', '));
})();
.as-console-wrapper {
max-height: none !important;
}
Upvotes: 2
Reputation: 1823
welcome! just remember to await
or then
the host async function as well
example:
async function a() {
return await http.get(...)
}
a() // undefined (promise awaiting resolve)
await a(); // expected value
a().then(value => console.log(value)) // expected value
in case of function a()
, you can just return the async task itself, which you will have to resolve later anyway:
function a() {
return http.get(...)
}
a() // undefined (promise awaiting resolve)
await a() // expected value
a().then(...) // expected value
also:
- you assigned this.ColorCode
to be a(n async) function, which means you will have to call it in order to get value retuned to it:
await Colors.ColorCheck('0'); // Colors.ColorCode and Colors.Color are now being assigned
await Colors.ColorCode(); // this.CodeC is being assigned to the class Colors + returned. which means from now on Colors.CodeC is also accessible
await Colors.Color() // assigns Colors.C a value + returns it. from now on Colors.C is also accessible
note that Colors.info is also assigned and overridden each time you call any of the functions (Colors.ColorCode / Colors.Color)
this
keyword is most likely misused: refer to this article in MDN. currently your values are stored within the class Colors
context, instead of probably just storing them in the function's context, using const
. e.g:const info = await axios...
const c = info.map(...);
return c;
Upvotes: 1
Reputation: 16266
You want to use string literals, but you are defining as a normal string:
this.info = await axios.get ('https://.../${ID}.json');
You should change to this:
this.info = await axios.get (`https://.../${ID}.json`);
Upvotes: -1