I don't know much about KeystoneJS. Anyway, here are my two cents:
const importData = [
{ name: 'A draft post', category: 'Keystone JS' },
// ...
];
importData
is an Array
which holds a bunch of Object
instances, each having a name
and category
key with String
values. For me, it appears this is some "mock data", which is simply put there for testing purposes.
I shifted the next parts, because it makes the code more understandable.
This part:
const categories = {};
Looks to me like the person who wrote it tried to implement some form of "caching". The categories
constant is a mere "container" to store posts in so they can be reused later instead of being recreated. The createPost
function reveals the purpose of it if you read through it.
const createPost = ({ name, category }) => {
let postCategory = new PostCategory.model({ category });
if (categories[category]) {
postCategory = categories[category];
}
categories[category] = postCategory;
const post = new Post.model({ name });
post.category = postCategory._id.toString();
return Promise.all([
post.save(),
postCategory.save()
]);
}
The first if
seems to be there to make use of the "caching" construct (const category
), but the way it does it is a bit confusing. Here's how I'd refactor it:
const createPost = ({ name, category }) => {
if (!categories[category]) {
categories[category] = new PostCategory.model({ category });;
}
const post = new Post.model({ name });
post.category = categories[category]._id.toString();
return Promise.all([
post.save(),
categories[category].save()
]);
}
Finally for the exports
part:
The module exports a function
which awaits a callback as argument (done
). It then tries to create a Promise
from all the "posts" of the mock data (and - to my understanding - fails), by mapping the createPost
function over it. The reason I think it fails is because Array.prototype.map
doesn't return a Promise
, it returns a new Array
instance which doesn't have a then
method (see next line). Instead of calling then
, it should be a Promise.all
again. When that final Promise
succeeds (or fails), the callback is called with the result.
exports = function (done) {
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importPromise.then(() => done()).catch(done);
};
Again, I'd rewrite it this way:
exports = function (done) {
Promise.all(importData.map(createPost)).then(done).catch(done);
};
Or just return
the final Promise
and get rid of the done
callback altogether.