Node postgres constraints - javascript

I'm trying to write a constraint code that will display a message when someone tries to search for an id that doesn't exist in the database (PostgreSQL) but the if statement code below doesn't seem to do anything I keep getting status 200 ok on postman even though the id doesn't seem to exist. How can I fix this?
Code below:
Database query:
const findFruit = async (req, res) => {
const {id } = req.params;
try {
const findfru = await pool.query("SELECT * FROM fruits WHERE fruit_id=$1", [id]);
if (!findfru ) {
return res.status(400).send(e)
}
res.json(findfru .rows[0])
} catch (e) {
res.status(500).send(e)
}
}
Route API:
router.get("Fruits/:id", findFruit )

If the ID isn't in the database the query still succeeds, it just returns no rows. You should check the number of rows explcitily:
if (findfru.rows.length === 0) {
return res.status(400).send(`${id} not found`);
}

Related

trying to remove an item from a database

Sorry If I'm not explaining this very well. I'm trying to delete from a database using this button press, but whenever I try to delete it will only delete the first item in the database. I'm pretty sure there's something wrong with the ID I'm getting. Can anyone spot any obvious issues I'm missing here?
Button Press:
tasksDOM.addEventListener('click', async (e) => {
const el = e.target
if (el.parentElement.classList.contains('delete-btn')) {
loadingDOM.style.visibility = 'visible'
const id = el.parentElement.dataset.id
try {
await axios.delete(`/tm/v1/tasks/${id}`)
showTasks()
} catch (error) {
console.log(error)
}
}
loadingDOM.style.visibility = 'hidden'
})
Delete:
app.delete("/tm/v1/tasks/:id", async (req, res) => {
try {
const id = req.params.id;
const response = await Task.findOneAndDelete({ id });
res.status(200).json({ msg: 'deleted' });
} catch (error) {
res.status(500).json({ msg: error });
};
});
Two solutions -
1. const response = await Task.findByIdAndDelete(id);
2. const response = await Task.findOneAndDelete({ _id : mongoose.Types.ObjectId(id) });
Don't forget to import mongoose for second method.
Explanation -
In your code findOneAndDelete is taking id as argument which doesn't exist for mongoose so default, its deleting the first entry so you need to use _id here. Second thing is, id param is string type and _id is ObjectId so it will not match. To match this, you need to convert this string value to mongoose ObjectId.
findByIdAndDelete works with string value as well!

Error while deleting a value of element in mongoDB array using filter function?

I tried to find the solutions over here but unable to get success while using $pull as the array values I have does not contain `mongo_id'.
So the scenario is that , I am trying to delete the specific comment of the particular user which I am passing through query params. M
My mongo data looks like this:
Now I am making API Delete request like this : http://localhost:8000/api/articles/learn-react/delete-comment?q=1 on my localhost .
ANd finally my code looks like this:
import express from "express";
import bodyParser from "body-parser";
import { MongoClient } from "MongoDB";
const withDB = async (operations, res) => {
try {
const client = await MongoClient.connect(
"mongodb://localhost:27017",
{ useNewUrlParser: true },
{ useUnifiedTopology: true }
);
const db = client.db("my-blog");
await operations(db);
client.close();
} catch (error) {
res.status(500).json({ message: "Error connecting to db", error });
}
};
app.delete("/api/articles/:name/delete-comment", (req, res) => {
const articleName = req.params.name;
const commentIndex = req.query.q;
withDB(async(db) => {
try{
const articleInfo = await db.collection('articles').findOne({name:articleName});
let articleAllComment = articleInfo.comments;
console.log("before =",articleAllComment)
const commentToBeDeleted = articleInfo.comments[commentIndex];
//console.log(commentToBeDeleted)
// articleAllComment.update({
// $pull: { 'comments':{username: commentToBeDeleted.username }}
// });
articleAllComment = articleAllComment.filter( (item) => item != commentToBeDeleted );
await articleAllComment.save();
console.log("after - ",articleAllComment);
//yaha per index chahiye per kaise milega pta nhi?
//articleInfo.comments = gives artcle comment
res.status(200).send(articleAllComment);
}
catch(err)
{
res.status(500).send("Error occurred")
}
},res);
});
I have used the filter function but it is not showing any error in terminal but also getting 500 status at postman.
Unable to figure out the error?
I believe you'll find a good answer here:
https://stackoverflow.com/a/4588909/9951599
Something to consider...
You can use MongoDB's built-in projection methods to simplify your code.
https://docs.mongodb.com/manual/reference/operator/projection/positional/#mongodb-projection-proj.-
By assigning a "unique ID" to each of your comments, you can find/modify the comment quickly using an update command instead of pulling out the comment by order in the array. This is more efficient, and much simpler. Plus, multiple read/writes at once won't interfere with this logic during busy times, ensuring that you're always deleting the right comment.
Solution #1: The recommended way, with atomic operators
Here is how you can let MongoDB pull it for you if you give each of your comments an ID.
await db.collection('articles').updateOne({ name:articleName },
{
$pull:{ "comments.id":commentID }
});
// Or
await db.collection('articles').updateOne({ name:articleName, "comments.id":commentID },
{
$unset:{ "comments.$":0 }
});
Solution #2 - Not recommended
Alternatively, you could remove it by index:
// I'm using "3" here staticly, put the index of your comment there instead.
db.collection('articles').updateOne({ name:articleName }, {
$unset : { "comments.3":0 }
})
I do not know why your filter is erroring, but I would recommend bypassing the filter altogether and try to utilize MongoDB's atomic system for you.

Firestore "where" query not working as expected

I am trying to do a simple query from my firestore data base but I am missing something very obvious. I tried looking online but nothing works. For some background, I have a "cf" collection where I am trying to query a the objects that have the "hsc" value equal to "1" but I don't get anything in return.
exports.getOneTodo = (request, response) => {
db
.collection('cf')
.where("hsc", "==", "1")
.get()
.then((doc) => {
if (!doc.exists) {
return response.status(404).json(
{
error: 'Todo not found'
});
}
TodoData = doc.data();
TodoData.todoId = doc.id;
return response.json(TodoData);
})
.catch((err) => {
console.error(err);
return response.status(500).json({ error: error.code });
});
};
Below are the firestore rules.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write
}
}
}
I am testing this via the postman. I have tried changing the firebase rules to be true for anything but still, nothing seems to be working.
UPDATE:
The following is how I initialized my DB
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
module.exports = { admin, db };
Your code is expecting a single document, but it has to be prepared for the query to return multiple documents. When you run get() on a Query object, it's going to yield a QuerySnapshot object. As you can see from the API documentation, it doesn't have an exists property. A check for that property will always be "false". What you have to do instead is check the results to first see if there were any documents, then get the first one:
db
.collection('cf')
.where("hsc", "==", "1")
.get()
.then((qsnapshot) => {
if (qsnapshot.docs.length > 0) {
const dsnapshot = qsnapshot.docs[0];
// send the response using dsnapshot.data()
}
else {
// send the response saying nothing was found
}
})
now you need to use
db.collection("id").whereGreaterThan("field","value")
.whereEqualTo("field","value")
.whereLessThen("field","value")

Res value is null in an app.get call done from vue.js front-end to express back-end

I am calling this code from the front-end and confirmed that there is a proper db connection and that the Id value is properly passed, and that there is a corresponding value in the database, but for some reason, res is null. What am I missing?
app.get("/api/walletlogin/user/:userId", (req, res) => {
id = req.params.userId
var query = {_id: id}
db.collection("Users").findOne(query, (err, result) => {
if (result) {
console.log(result.userName)
} else {
console.log('No User')
}
})
Here is the front-end call:
axios.get('/api/walletlogin/user/' + accounts)
.then((response) => {
console.log('Logged in With ' + accounts)
router.push('/account')
})
.catch((errors) => {
console.log('Cannot log in')
})
}).catch((err) => {
console.log(err, 'err!!')
})
You could try to convert your id to an objectID.
var ObjectId = require('mongodb').ObjectId;
var id = ObjectId(req.params.userId);
to search by id, you must use the ObjectID class from the mongodb package. Here is an example invented by me, it does not reflect the real work, but I hope it will become clear on it:
const { ObjectID } = require('mongodb');
const id = '5ee4f69bfa0b960de8aec158'; // in your example is req.params.userId
db.collection('users').findOne({ _id: new ObjectID(id)}, (error, result) => {
if (error) {
throw error;
}
console.log(result);
})
I am adding the details of the issue initially encountered in case someone else would experience it in the future. The value that is passed from the front-end is a cryptocurrency address. For some reason, some of the characters passed were upper-case, while the same address had been stored in the database with these same characters as lower case. Thus, one needs to add code to make sure that the case of the letters found in the respective addresses is ignored.
J

How can I use a variable saved from a mysql connection with NodeJS to an asynchronous function?

I'm trying to scrape a website with Puppeteer. I want to select the date of the last post inserted in my database and compare it to the dates taken by the scrape so I can see if the post is already in the database (using the date as the reference to see if it has been modified).
Here is my code:
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'db_webcrawler_coches'
});
connection.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
let lastpublishedDate;
let idCoches;
connection.query("SELECT id_coches, publish_date FROM coches ORDER BY publish_date DESC limit 1", function (err, row) {
if (err) throw err;
lastPublishedDate = row[0].publish_date;
idCoches = row[0].id_cochesNet;
console.log("Published in", lastPublishedDate);
console.log("Id Coches", idCoches);
});
const run = async () => {
try {
const options = {
headless: false,
};
...
const news = await page.evaluate(() => {
const idsList = [...document.querySelectorAll('div.mt-SerpList-item')].map(elem => elem.getAttribute("id")).filter(elem => elem.includes("#"))
const datePost = [...document.querySelectorAll('span.mt-CardAd-date')].map(elem => elem.innerText);
for(let i = 0; i < titlesCar.length; i++){
const finalDate = parsedDates[i];
if (finalDate > lastPublishedDate || idCoches !== idsList[i]){
console.log("Not repeated");
const carsList[i] = [
idsList[i],
parsedDates[i]
]
} else {
console.log("Repeated")
}
}
return carsList;
});
...
} catch (err) {
console.log(err);
await browser.close();
console.log("Browser Closed");
}
};
run();
As you can see I want to see if the date is the same or not as well as the id taken from the query. However, it appears an error that says Evaluation failed: ReferenceError: variable "lastPublishedDate" is not defined and I imagine that it will be the same with "idCoches". I wrote some console.logs to see when it crashes and it seems that it happens when reaches the function "news".
I'm not sure if it is because it is the scope or because of the function. What do you think I should do to make it work?
Could it be the scope?
Thank you!
EDIT: SOLVED!
I post it in the case that anyone faces a similar issue.
Indeed it was the scope, it is a problem related to Puppeteer. It seems that the function with page.evaluate() is unable to take any variable outside of it. To change it you need to add the page.evaluate in the following way:
await page.evaluate((variable_1, variable_2) => { /* ... */ }, variable_1, variable_2);
The callback to your Query probably does has not returned yet when the async function is run, so whatever your trying to reference is not defined.
I'm not sure if your mysql client supports promises, but if it does you could do something like this:
const run = async () => {
const row = await connection.query("SELECT id_coches, publish_date FROM coches ORDER BY publish_date DESC limit 1")
lastPublishedDate = row[0].publish_date;
idCoches = row[0].id_cochesNet;
...
}
If that does not work you could also run everything inside the callback of the query. Hope that helps.

Categories