Reputation: 631
I've come across a weird issue where a new variable is being created in local scope even if it is defined outside,
from the below code
after I call buildMeta() and check the contents of "data", it is always empty implying that it's not being modified at all, even if I've specifically targeted "that.data" where that refers to the class' object.
I'd appreciate if anyone would point out what I am doing wrong.
class meta {
constructor(files) {
if(!files) throw Error("files not specified");
this.data = {};
this.ls = files;
}
buildMeta() {
var that = this;
for(let i = 0; i < that.ls.length; i++) {
mm.parseFile(that.ls[i]).then(x => {
var info = x.common;
that.data[info.artist] = "test";
}).catch((x) => {
console.log(x);
});
}
}
}
const mm = new meta(indexer); // indexer is an array of file paths
mm.buildMeta();
console.log(mm.data);
Upvotes: 2
Views: 60
Reputation: 116
You're mixing sync with async code here.
The for loop won't wait for the parseFile
promises to resolve.
You could use Promise.all
to fill in the data when the files are parsed.
// Class names should be written using a capital letter
class Meta {
...
buildMeta() {
// You don't need this assignment since you're using arrow functions
// var that = this;
const promises = this.ls.map(filePath => mm.parseFile(filePath));
return Promise.all(promises).then(resolvedPromises => {
resolvedPromises.map(({ parsedFile }) => {
this.data[parsedFile.common.artist] = "test";
});
return this.data;
}).catch(console.error);
}
...
const mm = new meta(indexer); // indexer is an array of file paths
mm.buildMeta().then(data => {console.log(data)});
Hope this helps.
Upvotes: 2
Reputation: 13007
You are logging mm.data
before parseFile
has finished. Your code implies that it returns a promise, so your insertion into that.data
will happen after your console.log(mm.data)
executes.
You need to return a promise from buildMeta
, so that you can do...
const mm = new meta(indexer);
mm.buildMeta().then(() => {
console.log(mm.data);
})
Here's a buildMeta
that should do what you need. This returns a promise that waits for all of the parseFile invocations to do their work and update this.data
...
buildMeta() {
return Promise.all(this.ls.map(f => mm.parseFile(f).then(x => {
var info = x.common;
this.data[info.artist] = "test";
})))
}
Upvotes: 1