I want to be able to search by email (Just like it is done with MySQL) and it gives me the result expected in MongoDb
there are two things
1.) I want to have aquery where i can search for everything with MongoDB and get everything vis Email
My code is looking thus
const router = require("express").Router();
const Transaction = require("../models/Transactions");
router.get("/get-transactionby-email/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const trans = await Transaction.findById(req.params.email);
res.status(200).json(trans);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
But I am getting this Error back at Postman:
{
"message": "Cast to ObjectId failed for value \"john_kross2#yopmail.com\" (type string) at path \"_id\" for model \"Transactions\""
}
2.) How do i get all credits tranactions when I have colums called credit , debit and amount in the database using Node.js and Mongo DB
I managed to get it to work.
The code is looking thus :
const router = require("express").Router();
const Transaction = require("../models/Transactions");
router.get("/get-transactionby-email/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const trans = await Transaction.find({email: req.params.email});
res.status(200).json(trans);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
router.get("/get-credit-transaction/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const trans = await Transaction.find({email: req.params.email},{email:true,narration:true,credit:true,amount:true});
res.status(200).json(trans);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
router.get("/get-debit-transaction/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const trans = await Transaction.find({email: req.params.email},{email:true,narration:true,debit:true,amount:true});
res.status(200).json(trans);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
Thanks everyone.
Related
I want to do this in Node.JS
I want to have a link like this, it should be a GET Request
http://localhost:3000/api/bal/update-balance?email=aa#email.com&amount=4500
How can I do this in Node.JS
My code is looking Thus
const router = require("express").Router();
const User = require("../models/User");
const Trans = require("../models/Transactions");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
router.post("/update-balance", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const amount = parseInt(req.body.amount);
const user = await User.find({ email: req.body.email });
const balance = parseInt(user[0].balance);
//return balance;
//console.log(balance);
const total_amt = amount + balance;
//console.log(total_amt);
// update Balance
//const wallet_user = new User();
try{
await User.findOneAndUpdate({email : req.body.email}, {$set: {balance: total_amt}});
const transactions = new Trans({
email: req.body.email,
narration: 'NEW DEPOSIT - '+amount,
credit: amount,
debit: 0.00,
amount: amount,
});
transactions.save();
}catch(err){
console.log(err);
}
return res.send({ error: false, message: "OK" });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
Please See above Code.
router.get(("/update-balance"), async( req,res) => {
try {
const amount = req.query.amount;
const email = req.query.email;
//you can do the rest of the work here
}
catch (error) {
res.status(500).json({ message: error.message })
}
})
I had this error when I try to add a review using the curl command:
curl -X POST http://localhost:4444/api/v1/reviews/new -H “Content-Type:application/json” -d ‘{“movieId”:12,”user”:”sara”,”review”:”good”}’
reviews.controller.js
import reviewsDAO from "../dao/reviewsDAO.js";
export default class ReviewsController{
static async apiPostReview(req, res, next) {
try {
const movieId = parseInt(req.body.movieId)
const review = req.body.review
const user = req.body.user
console.log('movieId', movieId)
const reviewResponse = await reviewsDAO.addReview(
movieId,
user,
review
)
res.json({ status: "success" })
} catch (e) {
res.status(500).json({ error: e.message })
}
}
static async apiGetReview(req, res, next) {
try {
let id = req.params.id || {}
let review = await reviewsDAO.getReview(id)
if (!review) {
res.status(404).json({ error: "Not found" })
return
}
res.json(review)
} catch (e) {
console.log(`api, ${e}`)
res.status(500).json({ error: e })
}
}
static async apiUpdateReview(req, res, next) {
try {
const reviewId = req.params.id
const review = req.body.review
const user = req.body.user
const reviewResponse = await reviewsDAO.updateReview(
reviewId,
user,
review
)
var { error } = reviewResponse
if (error) {
res.status(400).json({ error })
}
if (reviewResponse.modifiedCount === 0) {
throw new Error(
"unable to update review",
)
}
res.json({ status: "success" })
} catch (e) {
res.status(500).json({ error: e.message })
}
}
static async apiDeleteReview(req, res, next) {
try {
const reviewId = req.params.id
const reviewResponse = await reviewsDAO.deleteReview(reviewId)
res.json({ status: "success" })
} catch (e) {
res.status(500).json({ error: e.message })
}
}
static async apiGetReviews(req, res, next) {
try {
let id = req.params.id || {}
let reviews = await reviewsDAO.getReviewsByMovieId(id)
if (!reviews) {
res.status(404).json({ error: "Not found" })
return
}
res.json(reviews)
} catch (e) {
console.log(`api, ${e}`)
res.status(500).json({ error: e })
}
}
}
I have tried several solutions but I didn't resolve the issue
reviewsDAO.js:
import mongodb from 'mongodb';
const ObjectID=mongodb.ObjectID;
let reviews;
export default class ReviewsDAO{
static async injectDB(conn){
if(reviews){
return
}
try{
reviews = await conn.db("reviews").collection("reviews");
} catch(e){
console.error(`Unable to establish collection handles in userDAO: ${e}..`);
};
};
static async addReview(movieId,user,review){
try{
const reviewDoc={
movieId:movieId,
user:user,
review:review
}
return await reviews.insertOne(reviewDoc);
}catch(e){
console.error(`Unable to post review: ${e}`);
return{error:e};
};
};
static async getReview(reviewId){
try{
return await reviews.findOne({_id:ObjectID(reviewId)})
}catch(e){
console.error(`Unable to get review: ${e}`);
return{error:e};
};
};
static async updateReview(reviewId,user,review){
try{
const updateResponse=await review.updateOne({_id:ObjectID(reviewId)},
{$set:{user:user,review:review}});
return updateResponse;
}catch(e){
console.error(`Unable to update review: ${e}`);
return{error:e};
};
};
static async getReviewByMovieId(movieId){
try{
const cursor=await reviews.find({movieId: parseInt(movieId)});
return cursor.toArray();
}catch(e){
console.error(`Unable to get review: ${e}`);
return{error:e};
};
};
};
reviews.route.js:
import express from 'express';
import ReviewsCtrl from "./reviews.controller.js";
const router=express.Router();
router.route("/movie/:id").get(ReviewsCtrl.apiGetReviews);
router.route("/new").post(ReviewsCtrl.apiPostReview);
router.route("/:id")
.get(ReviewsCtrl.apiGetReviews)
.put(ReviewsCtrl.apiUpdateReview)
.delete(ReviewsCtrl.apiDeleteReview)
export default router;
moviedb.js:
import app from './server.js';
import ReviewsDAO from "./dao/reviewsDAO.js";
import mongodb from 'mongodb';
import dotenv from 'dotenv';
const MongoClient=mongodb.MongoClient
dotenv.config();
const mongo_username = process.env.MONGO_USERNAME;
const mongo_password = process.env.MONGO_PASSWORD;
const port=4444;
MongoClient.connect(`mongodb+srv://${mongo_username}:${mongo_password}#cluster0.b5f7prn.mongodb.net/test`,
{
maxPoolSize: 50,
wtimeoutMS: 2500,
useNewUrlParser: true
})
.catch(err => {
console.error(err.stack)
console.error("Error connecting to the database:", err.message)
process.exit(1)
})
.then(async client => {
await ReviewsDAO.injectDB(client)
app.listen(port, () => {
console.log(`listening on port ${port}`)
})
})
i have this code i am trying to write, the code is supposed to update the balance in MongoDB after properly computing the balance. The challenge is , it does not, it properly computes the balance, but updating the column for the user, it does not update. Looking out to see where and how to update the balances only I have not seen anything to help.
My code is Looking thus :
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
router.post("/update-balance/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const amount = parseInt(req.body.amount);
const user = await User.find({ email: req.params.email });
const balance = parseInt(user[0].balance);
//return balance;
//console.log(balance);
const total_amt = amount + balance;
//console.log(total_amt);
// update Balance
const wallet_user = new User();
try{
await wallet_user.updateOne({email : req.params.email}, {$set: {balance: total_amt}});
}catch(err){
console.log(err);
}
return res.send({ error: false, message: "OK" });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
What Am I suppose to do that i am not doing rightly, kindly help.
The code above shows What I have attempted..
You can use $inc:
router.post('/update-balance/:email', async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer ') ||
!req.headers.authorization.split(' ')[1]
) {
return res.status(422).json({ message: 'Please Provide Token!' });
}
const amount = parseInt(req.body.amount);
try {
await User.findOneAndUpdate(
{ email: req.params.email },
{ $inc: { balance: amount } }
);
} catch (err) {
console.log(err);
}
return res.send({ error: false, message: 'OK' });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
How can i resolve it? If the API call doesn't resolve, it doesn't enter the database call, and it ends up in the catch
router.get('/pokemons', async (req, res) => {
try {
const { name } = req.query;
const apiName = await axios.get(`https://pokeapi.co/api/v2/pokemon/${name}`)
if (apiName) {
return res.status(200).json({
data: apiName.data.abilities
});
}
const dbName = await Pokemon.findAll({
where: {
name
}
})
return res.status(200).json({
data: dbName
})
} catch (err) {
res.status(404).json({
message: "No existe Pokemon con ese nombre",
error: err
})
}
});
It seems https://pokeapi.co/api/v2/pokemon API is either not responding fast or having some issue. if you are not having more control over this API, you can
Set timeout for API call. if within that time period API does not respond, do further action.
OR Try Below Code:
router.get('/pokemons', async (req, res) => {
try {
const { name } = req.query;
let apiName = "";
try {
apiName = await axios.get(`https://pokeapi.co/api/v2/pokemon/${name}`);
}
catch (err) {
console.log(err)
}
if (apiName != "") {
return res.status(200).json({
data: apiName.data.abilities
});
}
const dbName = await Pokemon.findAll({
where: {
name
}
})
return res.status(200).json({
data: dbName
})
} catch (err) {
res.status(404).json({
message: "No existe Pokemon con ese nombre",
error: err
})
}
});
I am trying to add test data for my test:
const chai = require("chai");
const expect = require("chai").expect;
chai.use(require("chai-http"));
const app = require("../server.js"); // Our app
const user = require("../app/controllers/user.controller.js");
describe("API endpoint /users", function() {
this.timeout(5000); // How long to wait for a response (ms)
before(function() {
const users = [
{
email: "ssss#ss.com",
givenName: "eee",
familyName: "www2"
},
{
email: "ssss#ss.com",
givenName: "eee",
familyName: "www2"
}
];
user.create(users);
done();
});
// GET - List all data
it("should return all users", function() {
return chai.request(app).get("/users").then(function(res) {
expect(res).to.have.status(200);
expect(res).to.be.json;
expect(res.body).to.be.an("array");
});
});
});
I get the error:
1) API endpoint /users
"before all" hook:
TypeError: Cannot destructure property email of 'undefined' or 'null'.
at Object.exports.create (app\controllers\user.controller.js:5:13)
How can I add test data?
Controller:
const user = require("../models/user.model.js");
const validator = require("email-validator");
// Create and Save a new user
exports.create = (req, res) => {
const { query: { email, givenName, familyName } } = req;
// Validate request
if (!validator.validate(email) || !givenName || !familyName) {
return res.status(400).send({
message:
"Please use a valid email address, given name and family name."
});
}
// Create a user
const User = new user({
email,
givenName,
familyName
});
// Save user in the database
User.save()
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Error occurred while creating the user."
});
});
};
// Retrieve and return all users from the database.
exports.findAll = (req, res) => {
user
.find()
.then(users => {
res.send(users);
})
.catch(err => {
res.status(500).send({
message:
err.message || "An error occurred while retrieving users."
});
});
};
// Find a single user with a userId
exports.findOne = (req, res) => {
user
.findById(req.params.userId)
.then(user => {
if (!user) {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
res.send(user);
})
.catch(err => {
if (err.kind === "ObjectId") {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
return res.status(500).send({
message: "Error retrieving user with id " + req.params.userId
});
});
};
// Update a user identified by the userId in the request
exports.update = (req, res) => {
// Validate Request
if (!req.body.content) {
return res.status(400).send({
message: "user content can not be empty"
});
}
// Find user and update it with the request body
user
.findByIdAndUpdate(
req.params.userId,
{
title: req.body.title || "Untitled user",
content: req.body.content
},
{ new: true }
)
.then(user => {
if (!user) {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
res.send(user);
})
.catch(err => {
if (err.kind === "ObjectId") {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
return res.status(500).send({
message: "Error updating user with id " + req.params.userId
});
});
};
// Delete a user with the specified userId in the request
exports.delete = (req, res) => {
user
.findByIdAndRemove(req.params.userId)
.then(user => {
if (!user) {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
res.send({ message: "user deleted successfully!" });
})
.catch(err => {
if (err.kind === "ObjectId" || err.name === "NotFound") {
return res.status(404).send({
message: "user not found with id " + req.params.userId
});
}
return res.status(500).send({
message: "Could not delete user with id " + req.params.userId
});
});
};
create function expects a single user while it receives an array of users as an argument. The problem with it is that it's a middleware, it doesn't return a promise, so it cannot be efficiently chained. It also causes side effects and calls res.send while this is not needed for what it's used here.
Mongoose model should be used directly here, its create accepts an array. The block should return a promise in order to not cause race conditions in tests:
const User = require(".../user.model.js");
...
before(function() {
const users = [...];
return User.create(users);
});