Creating a search endpoint in Mongo and NodeJS - javascript

I've been teaching myself basically a MERN CRUD project but haven't done anything on the front end as of yet. I have been able to get the API working properly on all the basic crud functionality. The thing I've been struggling with is constructing an endpoint that allows someone to search the MongoDB and return any matches.
I've been trying to pass a key that would be part of the HTTP GET request and use that with the Mongoose find function, but am not getting anywhere. I'll show what my working "findById" function looks like:
exports.findOne = (req, res) => {
App.findById(req.params.noteId)
.then((data) => {
if (!data) {
return res.status(404).send({
note: "Note not found with id " + req.params.noteId,
});
}
res.send(data);
})
.catch((err) => {
if (err.kind === "ObjectId") {
return res.status(404).send({
note: "Note not found with id " + req.params.noteId,
});
}
return res.status(500).send({
note: "Error retrieving note with id " + req.params.noteId,
});
});
};
So I tried to model the search function based off of that:
exports.search = async (req, res) => {
App.find(req.params.key)
.then((data) => {
if (!data) {
return res.status(404).send({
note: "Note not found with search query: " + req.params.key,
});
}
res.send(data);
})}
The error I'm getting is "Parameter "filter" to find() must be an object"
Any ideas appreciated, many thanks.

The error "The 'filter' parameter to find() must be an object" indicates that you are passing an invalid value to the find method. In this case, you are passing req.params.key as a parameter, but the find method expects to receive a filter object as a parameter.
To fix this error, just pass a valid filter object to the find method. For example, if you want to search for all documents that have the field "name" with the value "John", the code would be:

Related

Updating field value in a MongoDB document is turning string into object

I am currently making a project using React TypeScript, MongoDB, and Express.js. I am trying to update the field value in my MongoDB document, and it is supposed to be a string, but instead it is automatically turning it into an object. Has anyone had that problem before? If so, how did you fix it?
How it's supposed to be:
character_name: "string"
How it's updating:
character_name: {
"string": ""
}
I've even logged it in the console to show me the type of data, and it's saying it's a string, so I don't know what it could be doing?
The backend routes:
routes.put("/change-name", async (req, res) => {
const name = req.body as string;
try {
const client = await getClient();
const result = await client.db().collection<Account>('accounts').updateOne({ username: "AndrewDamas" }, {$set: {character_name: name}});
if (result.modifiedCount === 0) {
res.status(404).json({ message: "Not Found" });
} else {
res.json(name);
}
} catch (err) {
console.error("FAIL", err);
res.status(500).json({ message: "Internal Server Error" });
}
});
The service code on the frontend side:
export function changeName(name: string){
return axios.put(`${baseUrl}/change-name`, name)
.then(res => res.data);
}
And how I used it in my code:
function saveData(){
console.log(ourCharacterName);
changeName(ourCharacterName);
}
Any help would be greatly appreciated! Thanks.
Put request. When sending data as body, it's going to arrive as json in your server . So you can either deconstruct it or use dot notation in your route method.
return axios.put(`${baseUrl}/change-name`, {name:name})
Deconstruct the variable from the body
const {name} = req.body;
Update the document
... {$set: {character_name: name}}
Problem
Every time you use as in TypeScript it means that something is wrong.
const name = req.body as string;
Your body isn't really a string, your body is the object:
{
"string": ""
}
Solution
const { string: name } = req.body;

PG-Promise Proc Erroring Out with Unknown Parameter Type

We are attempting to write a PostgreSQL Procedure to insert data into a table. We have created the procedure and ran said procedure with the variables below and it inserts just fine. However, when we try to use pg-promise with our express server, our string parameters are being read as unknown. When we iterate over the post body, we see that each parameter is reading as the type we expect to go in, and PostgreSQL is reading integer correctly, but it isn't reading string correctly. I've attempted to use the as.text function and it sends in the parameter value as "''" but that still reads as unknown. Is there something we are missing to successfully post the data?
let createInspection = async (req, res, next) => {
try {
let params = [];
for (let prop in req.body) {
console.log(typeof req.body[prop]);
params.push(req.body[prop]);
}
console.log(params)
let data = await db.proc('Inspections_Create', params);
res.status(200)
.json({
status: 'success',
data: data,
message: 'Inserted Inspection'
});
}
catch (error) {
return next(error);
}
}

How to add conditional checks over ORM (sequelizejs) queries?

Suppose i have a table gameData {gameId, currentBoardLayout}, a get request like www.chess.com/asd123 is sent over to the server, where asd123 is my game id, I need to catch this id (asd123 which is my gameId) and check for it in my table (gameData) and implement the following logic :
srv.get('/:id', (req, res) => {
if ( gameData.findAll({where: {gameId: req.params.id} )
{ // Game room found
return currentBoardLayout
}
else
{ error : Invalid game id }
})
How can I achieve this?
Thanks
You can use Sequelize's findById method.
srv.get('/:id', (req, res) => {
gameData.findById(req.params.id)
.then(result => {
res.send(result)
})
.catch(() => {
res.send({
error: 'Could not find ID'
})
})
})
Here's what is happening:
Sequelize's findById method will return a promise. If it successful, you will get your item from the database back. If the item cannot be found, the catch method will fire.
res.send is Express' way of sending data back to the client.
It is worth checking out the Sequelize docs:
Using models
Querying

Trouble Returning Different Variables from Mongo using NodeJS

So I have a function that when you pass a username as an argument it queries a MongoDB database and returns the document containing that username. So in the function, I check to see if the document exists containing the username, and if it doesn't I return the document that has an empty string as the username. So kind of like, return default if doesn't exist. So I assume that if it doesn't find a matching document it returns an undefined object.
Ideally, I want a function that when called will either return a default document retrieved from a database when the username doesn't exist or return the corresponding document for the username passed as an argument. Maybe the problems are trying to read or return variables before they exist because of the asynchronous nature of the calls.
I really don't think major restructuring of the code is a good idea, because I'm trying to work with three asynchronous libraries and connect them all together. I have multiple asynchronous classes in recursive processing functions.
getContext(username = '') {
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/tc-db', function (err, db) {
if (err) {
console.log(err);
} else {
db.collection('chatters').findOne({ username: username }, function (err, results) {
if (err) {
throw err;
} else if (results === undefined) {
db.collection('chatters').findOne({ username: '' }, function (err, results) {
console.log('Notifier');
console.log('Get if Null: ' + JSON.stringify(results));
return JSON.stringify(results.context);
});
} else {
console.log('Notifier 2');
return JSON.stringify(results.context);
}
});
}
});
}
The actual error I'm getting alot when running the function, especially with a username that doesn't exist in the database is "Can't read property 'context' of null". Thank you guys so much for any help you can offer.

Find one element, use data, then delete it

In my node.js application I'm currently implementing a "Remember Me" functionality. Everything works quite well so far, but I have a problem with mongoose. What I want to do: I have a model named Token with this schema:
var TokenSchema = mongoose.Schema({
token: { type: String },
uid: { type: Schema.Types.ObjectId, ref: 'User' }
});
This is simply a little collection that maps cookie tokens to a UserId. Then I have this function here:
function consumeRememberMeToken(token, fn) {
Token
.findOne({ 'token': token }, (err, result) => {
return (result===null)?fn(null, null):fn(null, result.uid);
})
.remove();
}
What it should do, is this: find the uid for a given token string and return it (if there is a result). But this function should also delete the entry right after returning the uid.
At the moment, the uid from the found token result gets returned properly, but it (the result Token) does not get deleted from the collection with the above code. I don't understand how to remove it right after getting it and using the retrieved uid. I'm completely new to functional programming and I don't understand how and where to delete the token.
You can try db.collection.findOneAndDelete It deletes the document and returns the deleted data, quite the reverse of what you are saying but basically serves your purpose. here are the details.
Also here is the mongoose representation of the same.
Token.findOne({ 'token': token }, (err, result) => {
if(err || !result) return fn(err || "error", null);
else{
var uid = result.uid;
result.remove(function(){
return fn(null, uid);
});
}
})

Categories

Resources