Reputation: 466
I am supposed to refactor the below code and I did that (see image).
My lead is still not happy with it LOL.
const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
const fromDate = moment(input.requestDate)
.subtract(retention, 'days')
.toISOString();
if (input.targetId && !input.userId) {
// with target id and no user id
let query = this.model
.query('appTargetId')
.eq(appTargetId)
.where('createDate')
.ge(fromDate)
.where('status')
.not()
.eq(NotificationStatus.Delete);
/* istanbul ignore next */
if (input.subApplicationId) {
query = query.filter('subApplicationId').eq(input.subApplicationId);
}
return query.exec();
} else if (input.userId && !input.targetId) {
// with user id and no target id
return this.model
.query('appUserId')
.eq(appUserId)
.where('createDate')
.ge(fromDate)
.where('status')
.not()
.eq(NotificationStatus.Delete)
.exec();
} else {
// user id + target id
return this.model
.query('appUserTargetId')
.eq(appUserTargetId)
.where('createDate')
.ge(fromDate)
.where('status')
.not()
.eq(NotificationStatus.Delete)
.exec();
}
How else can I write this??
Spent so many hours trying to move, mend and bend this piece of code.
Anyone out there with a better solution??
Upvotes: 2
Views: 233
Reputation: 1285
Here is a bit better optimized version of it. Avoiding multiple if loops and shorter code.
const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
const fromDate = moment(input.requestDate)
.subtract(retention, 'days')
.toISOString();
const index = (input.targetId ? (input.userId ? {"appUserTargetId" : appUserTargetId} : {"appTargetId": appTargetId}) : {"appUserId" : appUserId};
let query = this.model
.query(Object.keys(index)[0])
.eq(Object.values(index)[0])
.where('createDate')
.ge(fromDate)
.where('status')
.not()
.eq(NotificationStatus.Delete);
if (input.subApplicationId) {
query = query.filter('subApplicationId').eq(input.subApplicationId);
}
return query.exec();
If the reviewer is not in favour of single line multiple ternary operator, you could try one of these two options.
(targetId && userId && {"appUserTargetId" : appUserTargetId}) || (targetId && {'appTargetId' : appTargetId}) || (userId && {'appUserId': appUserId})
[OR]
Do Object Oriented Javascript (OOJS). Create a base class and 3 extended classes. Each of the 3 extended class correspond to the if case. Here is the details on the basics of OOJS
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
Upvotes: 1
Reputation: 1028
I think this strikes a good balance between terseness and clarity.
For 1/pair of arrows) I think the index/indexstring variables are kind of cumbersome, so I just built it into the if statement.
For 2) I personally find the .where().not().eq() chains and comparable much clearer/easier to read on a single line than spread out like that.
For 3) you can consolidate that to a single return.
const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
const fromDate = moment(input.requestDate)
.subtract(retention, 'days').toISOString();
// Since the point of this function is query-building, we need it available through the whole thing.
let query;
// Single ifs are clearer
if (input.targetId) {
if (input.userId) {
query = this.model.query('appUserTargetId').eq(appUserTargetId);
} else {
query = this.model.query('appTargetId').eq(appTargetId);
}
} else {
query = this.model.query('appUserId').eq(appUserId);
}
// This part is common
query = query
.where('createDate').ge(fromDate)
.where('status').not().eq(NotificationStatus.Delete);
// Not sure if this depends on being conditioned on all 3 or if just subApplicationId would suffice
/* istanbul ignore next */
if (input.subApplicationId && input.targetId && !input.userId) {
query = query.filter('subApplicationId').eq(input.subApplicationId);
}
// Execute the query
return query.exec();
Upvotes: 2
Reputation: 194
Try this:
const { appTargetId, appUserTargetId, appUserId } = buildIndexKeys(input);
const fromDate = moment(input.requestDate)
.subtract(retention, 'days')
.toISOString();
let indexString;
let index;
if (input.targetId && !input.userId) {
// with target id and no user id
indexString = 'appTargetId';
index = appTargetId;
/* istanbul ignore next */
} else if (input.userId && !input.targetId) {
// with user id and no target id
indexString = 'appUserId';
index = appUserId;
} else {
// user id + target id
indexString = 'appUserTargetId';
index = appUserTargetId;
}
let query;
if (input.subApplicationId) {
query = query.filter('subApplicationId').eq(input.subApplicationId);
} else {
query = this.model
.query(indexString)
.eq(index)
.where('createDate')
.ge(fromDate)
.where('status')
.not()
.eq(NotificationStatus.Delete)
}
return query.exec();
Upvotes: 1