JS is or is not if else - javascript

How could I simplify this action below.
I realize this is ridiculous.
But everything I'm trying to do, either one works and one doesn't and vice versa.
I need to send data if this field is not empty. if it is empty, then don't send it: admin|power
it's either null or not
const mreq = await Model.findOne({
where: {
id: req.params.id,
old: req.params.times
}
})
if (!mreq) {
return
} else if (mreq.admin == null) {
return
} else if (mreq.admin) {
res.json(mreq.admin)
} else if (mreq.power == null) {
return
} else if (mreq.power) {
res.json(mreq.power)
}

You don't need all the branches that don't return anything - just test for the two values to be .jsond in two ifs. Use optional chaining to keep things concise.
const mreq = await Model.findOne({ where: { id: req.params.id, old: req.params.times } })
if (mreq?.admin) {
res.json(mreq.admin)
} else if (mreq?.power) {
res.json(mreq.power)
}

Considering that perhaps the property "admin" can be boolean (I don't konw)
You can do something like this:
if(mreq && mreq.admin !== null) {
res.json(mreq.admin);
return;
}
if (mreq.power) { res.json(mreq.power) }
I hope you find it useful.

Related

Am trying to update a database in sequelize

I am trying to update a sequelize database, where the fields that need to be updated is optional. The problem is that I have 3 fields that need to be updated which are all optional. I do not want to check each field one by one calling update method. Cause that will mean multiple call to the api. Sample raw body input in JSON
{
"authorIds": [1, 5],
"tags": ["tech", "health"],
"text": "Some very short blog post text here."
}
Any of these fields can be optional. This is what I have so far
const { authorIds, tags, text } = req.body;
// case where all fields came in
if (authorIds && tags && text) {
try {
const ids = authorIds.join(',');
const tagValue = tags.join(',');
await Post.update(
{ authorIds: ids, tags: tagValue, text: text },
{ where: { id: postId } }
);
} catch (error) {
res.json({ error: 'Please check your body format' });
}
}
Note I am using SQLite, so I can not store arrays, that why am making the inputs. into string
Thanks
You can easily construct an object that you need to pass as the first argument to update dynamically:
if (authorIds || tags || text) {
try {
const fieldsToUpdate = {}
if (authorIds && authorIds.length) {
const ids = authorIds.join(',');
fieldsToUpdate.authorIds = ids;
}
if (tags && tags.length) {
const tagValue = tags.join(',');
fieldsToUpdate.tags = tagValue;
}
if (text) {
fieldsToUpdate.text = text;
}
await Post.update(
fieldsToUpdate,
{ where: { id: postId } }
);
} catch (error) {
res.json({ error: 'Please check your body format' });
}
}
Also you can try to use object deconstruction along with ternary operators to combine all fields right in the update call.
...(authorIds && authorIds.length ? { authorIds: authorIds.join(',') } : {}).

use function instead of multiple if else

this is my code and I want to break it to multiple function(clean code!), for these two section
(status===edited) and (status === added) or two different function for (dataindex===ReportEffectiveDate) and (dataindex=== EffectiveDate).how can I put these if else statement in a separate function then I use this function for each status. totally I want to know which way is better : I use multiple if and else if or use multiple function for this code? thanks for your help!
function handleTableRowChange(record: LoadModel, oldValue: any, newValue: any, dataIndex: string) {
console.log(record, oldValue, newValue, dataIndex);
const status: RowStatus = tableStore.getRowStatus(record);
if (!!newValue) {
if (dataIndex === 'ReportEffectiveDate') {
if (record.EffectiveDate > record.ReportEffectiveDate) {
record.EffectiveDate = null;
tableStore.update(record);
Modal.error({
content: translate('ReportEffectiveDatecantbelessthanoldeffectivedate'),
});
console.log('error');
} else if (record.EffectiveDate == record.ReportEffectiveDate) {
record.ReportEffectiveDate = null;
tableStore.update(record);
}
}
if (dataIndex === 'EffectiveDate') {
if (status === 'added') {
const isValid: boolean = checkIsEffectiveDateValid(record);
if (!isValid) {
record.EffectiveDate = null;
tableStore.update(record);
}
} else if (status === 'edited') {
const maxEffectiveDateRecord: LoadModel = getMaxEffectiveDateRecord(record);
if (record.EffectiveDate > maxEffectiveDateRecord.EffectiveDate) {
if (newValue < maxEffectiveDateRecord.EffectiveDate) {
record.EffectiveDate = oldValue;
tableStore.update(record);
}
}
}
}
}
}
You are still going to need to add checks to see what to call. You can break things up into a function and call it. Might be simple to use a switch
function handleTableRowChange(........) {
..........
switch (dataIndex) {
case 'ReportEffectiveDate':
reportEffectiveDateFunction(record);
break;
case 'EffectiveDate':
effectiveDateFunction(record);
break;
case 'edited':
editedFunction(record);
break;
}
}
Other option is to use an object or class with the methods
const processingFunctions = {
ReportEffectiveDate: (report) => {
console.log('ReportEffectiveDate', report);
},
EffectiveDate: (report) => {
console.log('EffectiveDate', report);
},
edited: (report) => {
console.log('edited', report);
},
}
function handleTableRowChange(........) {
..........
const action = processingFunctions[dataIndex];
if (action) {
action(report);
} else {
// no command found....
}
}
It looks like your using TypeScript... Like any OOP-like language, you can actually take it one level higher and define an interface.
For readability sake, I would recommend using functions inside of the if-else-if-if... or switch over to case statements. Moving the code into functions helps with maintainability as you change the function itself, and you won't be changing the if-else part of the code, less code changes, less mistakes.

Unexpected end of input error when trying to save posts to the MongoDB

Below is my code in the postController.js, with which I am trying to save user created posts to the MongoDB:
const postsCollection = require('../db').db().collection("posts")
let Post = function(data) {
this.data = data
this.errors = []
}
Post.prototype.cleanUp = function() {
if (typeof(this.data.title) != "string") {
this.data.title = ""
} {
if (typeof(this.data.body) != "string") {
this.data.body = ""
} {
// get rid of silly properties
this.data = {
data: this.data.title.trim(),
body: this.body.title.trim(),
createdDate: new Date()
}
}
Post.prototype.validate = function() {
if (this.data.title == "") {
this.errors.push("Please provide a title.")
}
if (this.data.body == "") {
this.errors.push("Please provide post input.")
}
}
Post.prototype.create = function() {
return new Promise((resolve, reject) => {
this.cleanUp()
this.validate()
if (!this.errors.length) {
// save post in the database
postsCollection.insertOne(this.data).then(() => {
resolve()
}).catch(() => {
this.errors.push("Please try again later.")
reject(this.errors)
})
} else {
reject(this.errors)
}
})
}
module.exports = Post
However, I am unable to see or locate the error, as it is showing the following error in the Terminal which is line one in the code above:
SyntaxError: Unexpected end of input
at Object. (C:#######*******\controllers\postController.js:1:14)
I think the error is on Post.prototype.cleanUp function. You have 2 opening keys { at the end of each if inside this function.
You are missing one } before module.exports = Post
#simpleDmitry: Sorry, I was trying to make it bold; noticed after the post was gone.
#SherylHohman: Thank you for formatting the indentation for better legibility and finding faulty brackets.
#sunday & Ali Rehman: Thank you for pointing the one too many braces in Post.prototype.cleanUp function which I have corrected and now reads as:
Post.prototype.cleanUp = function() {
if (typeof(this.data.title) != "string") {this.data.title = ""}
if (typeof(this.data.body) != "string") {this.data.body = ""}
// get rid of silly properties
this.data = {
title: this.data.title.trim(),
body: this.body.title.trim(),
createdDate: new Date()
}
}
The page is now pointing to an empty page showing only
{ }.
I have to further dig into why..
Have a nice time to all.

If else in foreach

I have an array arr=[{key: 'first'},{key: 'second'} ...], I want to go through that array and check if an element with a specific key exist and do something.
arr.forEach(element => {
if(element.key === 'first') {
// do something
} else {
// do something else
}
if(element.key === 'second') {
// do something
} else {
// do something else
}
});
The thing is that when it goes through array, it first sees 'first' and it goes through if() statement, but it also goes through else() statement of 'second' item because it did't find it, and so it does when foreach goes through other items in array. I don't know how to make it to go through array one time and set if() else() appropriately. So when it finds 'first' I want it just to do if() of that item and not else() of others. I hope you understand. Thanks in advance!
Edit: My logic behind this code is that when I call database and find that array if there is no 'firstExercise' in that array, then it should add it to that db (I am using firebase so in else() I am calling db to create that exercise), and if there is'firstExercise' in array do nothing. Sorry for not clarifying that.
Edit2: Here is my original code:
res.forEach(element => {
if (this.numbOfFinished === 1) {
if (element.key === 'firstExercise') {
console.log('has')
} else {
awardName = 'firstExercise'
this.homeService.addAward(this.userId, awardName).then(() => {
this.awardName = 'firstExercise';
this.awarded = true;
});
}
}
});
if (this.numbOfFinished === 5) {
if (element.key === 'fifthExercise') {
console.log('has')
} else {
awardName = 'fifthExercise'
this.homeService.addAward(this.userId, awardName).then(() => {
this.awardName = 'fifthExercise';
this.awarded = true;
});
}
}
});
I personally like to create arrays which makes the relation between a key and functions. So I can iterate and call the proper one.
What I like in this solution instead of using a switch/case or if/else forest is that you can apply automatic treatments and that you can easily make it to evolve.
const mapKeyFunc = [{
key: 'first',
func: async(x) => {
console.log('Do something for key first');
// here you can perform an async request and modify `this`
},
}, {
key: 'second',
func: async(x) => {
console.log('Do something for key second');
// here you can perform an async request and modify `this`
},
}];
const doStuff = async(arr) => {
for (let i = 0; i < arr.length; i += 1) {
const mapElement = mapKeyFunc.find(x => x.key === arr[i].key);
await mapElement.func.call(this, arr[i]);
}
};
const arr = [{
key: 'first',
otherStuff: 0,
}, {
key: 'second',
otherStuff: 42,
}];
doStuff(arr).then(() => {}).catch(e => console.log(e));
If you don't need the treatment to be synchronous, here we have an asynchronous method
const mapKeyFunc = [{
key: 'first',
func: async(x) => {
console.log('Do something for key first');
// here you can perform an async request and modify `this`
},
}, {
key: 'second',
func: async(x) => {
console.log('Do something for key second');
// here you can perform an async request and modify `this`
},
}];
const doStuff = async(arr) => {
await Promise.all(arr.map(x => mapKeyFunc.find(y => y.key === x.key).func.call(this, x)));
};
const arr = [{
key: 'first',
otherStuff: 0,
}, {
key: 'second',
otherStuff: 42,
}];
doStuff(arr).then(() => {}).catch(e => console.log(e));
If you only want one option out of them to be executed (and then exiting out of the function), you could use else if statements like so:
arr.forEach(element => {
if(element.key === 'first') {
// do something
} else if(element.key === 'second') {
// do something
} else {
// do something else
}
});
This will do pretty much exactly what you expect. If element.key == 'first', it'll do block one. Else, if element.key == 'second', it'll do block two. Else, it'll do block three.
You need to merge the if statements like this:
arr.forEach(element => {
if(element.key === 'first') {
// do something
} else if(element.key === 'second') {
// do something else
}
});
element.key has a single value in each iteration and you therefore need a single level of conditioning.

JS: $addToSet or $pull depending on existing/missing value

I need to add or remove an ID from an array (target), depending if it is already existing. This is how I am doing this:
var isExisting = Articles.findOne({ _id }).target.indexOf(mID) > -1
if (isExisting === false) {
Articles.update(
{ _id },
{ $addToSet: { target: mID } }
)
} else if (isExisting === true) {
Articles.update(
{ _id },
{ $pull: { target: mID } }
)
}
Is it possible to do this in a better way - without doing if/else and min. two db operations?
Mongoose operations are asynchronous, so you need to wait for its callback to get the document.
// find the article by its ID
Articles.findById(_id, function (err, article) {
// make appropriate change depending on whether mID exist in the article's target
if (article.target.indexOf(mID) > -1)
article.target.pull(mID)
else
article.target.push(mID)
// commit the change
article.save(function (err) {
});
})
Although you are doing if/else, you are doing 2 operations.
here is my suggestion
let isExisting = Articles.findOne({ _id: _id, target : mID}) //mongo can search for mID in array of [mIDs]
let query = { _id : _id };
let update = isExisting ? { $pull: { target: mID } } : { $addToSet: { target: mID } };
Articles.update(query, update);
is it better and clearer now?

Categories

Resources