I want to display orderSchema in the frontend which is a subdocument. My subdocuments are objects which have a unique obiect id. As I am able to get the userSchema but not able to get orderSchema on the frontend do I need to make some changes in getServerSideProps function?
To take a deeper look you can checkout my repo - https://github.com/Sarab71/Git-optics
Model
import mongoose from 'mongoose'
const orderSchema = new mongoose.Schema({
rsph: { type: Number },
rcyl: { type: Number },
raxis: { type: Number },
lsph: { type: Number },
lcyl: { type: Number },
laxis: { type: Number },
add: { type: Number },
frame: { type: String },
lens: { type: String }
}, {
timestamps: true
});
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
phone: { type: Number, required: true },
address: { type: String, required: true },
orders: [orderSchema]
}, {
timestamps: true
});
export default mongoose.models.User || mongoose.model('User', userSchema)
Api
import User from "../../../models/addUser";
import initDB from "../../../helper/initDB";
initDB()
export default async (req, res) => {
switch (req.method) {
case "GET":
await getUser(req, res)
break;
}
}
const getUser = async (req, res) => {
const { uid } = req.query
const user = await User.findOne({ _id: uid })
res.status(200).json(user)
}
FrontEnd
I am using getServerSideProps for the FrontEnd
export async function getServerSideProps({ params: { id } }) {
const res = await fetch(`${baseUrl}/api/user/${id}`)
const data = await res.json()
return {
props: { user: data }
}
}
Related
I am creating a blog that will have the home screen where all the recipes will be rendered with a button on each recipe to add to favorites, also the favorites screen where will have all the user's favorite recipes.
So I made my models like this:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const Recipe = mongoose.model(
'Recipe',
new Schema(
{
name: {
type: String,
required: true,
},
ingredients: {
type: String,
required: true,
},
preparation: {
type: String,
required: true,
},
time: {
type: String,
required: true,
},
portion: {
type: String,
required: true,
},
imageName: {
type: String,
required: true
},
imageSize: {
type: Number,
required: true
},
imageKey: {
type: String,
required: true
},
imageUrl: {
type: String,
},
category: Object
},
{ timestamps: true }
)
);
module.exports = Recipe;
const mongoose = require('mongoose');
const { Schema } = mongoose;
const Favorite = mongoose.model(
'Favorite',
new Schema(
{
like: {
type: Boolean,
default: false,
},
recipes: Object,
user: Object,
},
{ timestamps: true }
)
);
module.exports = Favorite;
The bookmark button should change color according to whether like in the bookmark model is true or false but in this case I would not have access to it when I do get for recipes. How can I solve this? In sql I could solve it with relationship but in nosql I don't know how to solve it.
get recipes:
static async getRecipes(req, res) {
const page = req.query.page || 1;
const search = req.query.search || '';
const limit = 10;
const count = await Recipe.find().count();
const totalPages = Math.ceil(count / limit);
if (page > totalPages || page <= 0) {
res.status(400).send({ msg: 'invalid page!' });
return;
}
const recipes = await Recipe.find({
name: { $regex: search, $options: 'i' },
})
.sort('-createdAt')
.limit(limit * 1)
.skip((page - 1) * limit);
res.status(200).json({ recipes: recipes, page, limit, totalPages });
}
get favorites:
static async getAllFavorites(req, res) {
const { page = 1, limit = 10 } = req.query;
// get token
const token = getToken(req);
const user = await getUserByToken(token);
const favorites = await Favorite.find({ 'user._id': user._id })
.sort('-createdAt')
.limit(limit * 1)
.skip((page - 1) * limit);
res.status(200).json({ favorites: favorites, page, limit });
}
I am new to learning web dev using node.js and express.js. When I test my code in Postman the server crashes and gives me this error this.$__.validationError = new ValidationError(this).
I am creating backend server connected to MongoDB and the mongoose package.
Routes
const express = require('express')
const router = express.Router()
const {
create
} = require('./../controllers/courseControllers')
const {verifyAdmin, verify} = require('./../auth')
router.post('/create', verifyAdmin, async (req, res) => {
// console.log(req.body)
try{
create(req.body).then(result => res.send(result))
}catch(err){
res.status(500).json(err)
}
})
Controllers
const Course = require('../models/Course');
//CREATE A COURSE
module.exports.create = async (reqBody) => {
const {courseName, description, price} = reqBody
let newCourse = new Course({
courseName: courseName,
description: description,
price: price
})
// console.log(newCourse)
return await newCourse.save().then((result, err) => result ? result : err)
}
Schema
const mongoose = require('mongoose');
const courseSchema = new mongoose.Schema({
courseName: {
type: String,
required: [true, `Course name is required`],
unique: true
},
description: {
type: String,
required: [true, `Course description is required`]
},
price: {
type: Number,
required: [true, `Price is required`]
},
isOffered: {
type: Boolean,
default: true
},
enrollees: [
{
userId: {
type: String,
required: [true, `userId is required`]
},
enrolledOn: {
type: Date,
default: new Date()
}
}
]
}, {timestamps: true})
module.exports = mongoose.model("Course", courseSchema);
Given the information you provided, i can say that you are missing the enrollees parameter on creation whitin the controller, as enrollees has been set to required, i hope its usefull for you, if not let me know.
I want to find each of the elements in the array by their id and send it with the post request to create a new post. Right now when I create a new post only passes the first index of the array and if I use find() it passes all of the social schemas regardless if it is in the body of the request. I hope this makes sense if it doesn't please let me know. I hope someone can help.
Below is the mongoose schema for the qrcode post also using Joi
const Joi = require("joi");
const mongoose = require("mongoose");
const { themeSchema } = require("./Theme");
const { userSchema } = require("./User");
const { socialSchema } = require("./Social");
const QrCode = mongoose.model(
"QrCode",
new mongoose.Schema({
user: {
type: userSchema,
required: true,
},
name: {
type: String,
maxLength: 255,
required: true,
trim: true,
},
theme: {
type: themeSchema,
required: true,
},
// Social Media Links
social: [
{
type: socialSchema,
required: true,
},
],
})
);
function ValidateQrCode(qrCode) {
const schema = {
userId: Joi.objectId(),
name: Joi.string().max(255).required(),
themeId: Joi.objectId().required(),
socialId: Joi.array().required(),
};
return Joi.validate(qrCode, schema);
}
module.exports.QrCode = QrCode;
module.exports.validate = ValidateQrCode;
this is the post route to create a new qrcode
router.post("/", auth, async (req, res) => {
const { error } = validate(req.body);
if (error) res.status(400).send(error.details[0].message);
const theme = await Theme.findById(req.body.themeId);
if (!theme) return res.status(400).send("Invalid theme.");
const user = await User.findById(req.user._id);
if (!user) return res.status(400).send("Invalid theme.");
const social = await Social.findById(req.body.socialId);
if (!social) return res.status(400).send("Invalid social.");
const qrCode = new QrCode({
user: user,
name: req.body.name,
theme: theme,
social: social,
});
await qrCode.save();
res.send(qrCode);
});
In the body of my Postman request I am inputting the info below
{
"name": "Friends",
"themeId": "60f89e0c659ff827ddcce384",
"socialId": [
"60f89e43659ff827ddcce386",
"60f89e5c659ff827ddcce388"
]
}
To fetch data using ids, you can use below mongodb query simply,
db.collection.find( { _id : { $in : ["1", "2"] } } );
In mongoose,
model.find({
'_id': { $in: [
mongoose.Types.ObjectId('1'),
mongoose.Types.ObjectId('2'),
mongoose.Types.ObjectId('3')
]}
}, function(err, docs){
console.log(docs);
});
Or
await Model.find({ '_id': { $in: ids } });
So am still kinda new to nodejs and am currently on a project and would to integrate a referral sytem into it. Basically on registering a user has a generated unique url that ither users can register with, i have gotten pass this part but now am trying to link the new user and the user who owns the link.
Here are my Models:
Referral Model
import mongoose, { mongo } from 'mongoose';
const referralSchema = new mongoose.Schema({
referralId: [
{
type: String,
unique: true
}
],
referralLink: {
type: String,
unique: true
},
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
createdAt: {
type: Date,
default: Date.now()
}
})
const Referral = mongoose.model("Referral", referralSchema);
export default Referral;
User Model
import mongoose from 'mongoose';
import passportLocalMongoose from 'passport-local-mongoose'
const userSchema = new mongoose.Schema({
firstName: String,
lastName: String,
email: {
type: String,
trim: true,
required: true,
unique: true,
lowercase: true
},
emailToken: String,
isVerified: Boolean,
username: String,
password: String,
isAdmin: Boolean,
refId: {
type: mongoose.Schema.Types.ObjectId,
ref: "referral",
},
walletId: {
type: mongoose.Schema.Types.ObjectId,
ref: "wallet",
},
plan: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "plan",
}
]
})
userSchema.plugin(passportLocalMongoose);
const User = mongoose.model("User", userSchema);
export default User;
And Here is my code
router.get('/verify-email', async (req, res, next) => {
try {
const user = await User.findOne({ emailToken: req.query.token });
if (!user) {
req.flash('error', 'Token is invalid, Please contact us for assistance');
return res.redirect('/');
}
user.emailToken = null;
user.isVerified = true;
const savedUser = await user.save().then((user) => {
//Create new referral for new user
const newReferrer = new Referral({
referralId: uuidv4(),
referralLink: uuidv4(),
userId: user._id,
});
//save referral to the database
newReferrer.save()
const customUserResponse = { user: savedUser }
customUserResponse.refCode = newReferrer.referralId
req.login(user, async (err) => {
if (err)
return next(err);
req.flash('success', `Welcome to Jenerouszy Mechanism ${user.username}`);
const redirectUrl = req.session.redirectTo || `/dashboard`;
delete req.session.redirectTo;
res.redirect(redirectUrl);
});
});
} catch (error) {
console.log(error);
req.flash('error', 'Something went wrong, please try again or contact us for assistance')
res.redirect('/')
}
});
router.get("/referrals", middlewareObj.isLoggedIn, (req, res) => {
Referral.findOne({ userId: req.user._id })
.populate('user') //Populate model with user
.then(loggedUser => {
//Generate random referral link
const generatedRefLink = `${req.protocol}://${req.headers.host}/register?reflink=${loggedUser.referralLink}/dashboard`
res.render('dashboard/referrals', {
loggedUser: loggedUser,
generatedRefLink: generatedRefLink
})
})
})
I don't know how to go about this, can someone please guide me on what to do.
I have a "Drinkers" model and a "Sodas" model which is "related" - a drinker can have drunk X amount of sodas.
The route to get the data is this
router.get('/all/:drinkerId', sodasController.getAllSodasFromDrinker)
In my sodasController, is there a way to check if :drinkerId exists in the "Drinkers" collection and if not return an error that the drinker doesn't exist, without having to require the drinkersController in the sodasController.
Right now getAllSodasFromDrinker looks like this
const Sodas = require("../models/sodas.model");
exports.getAllSodasFromDrinker = async (req, res, next) => {
try {
const id = req.params.drinkerId;
if (id.match(/^[0-9a-fA-F]{24}$/)) {
await Sodas.find({ drinker: id }).exec((err, drinkerItem) => {
if (err) {
return next(err);
}
res.json({ data: drinkerItem });
});
} else {
return next("ID is in the wrong format");
}
} catch (error) {
return next(error);
}
};
In that function, I want to check if a user exists with the applied ID.
I want to avoid having to
const Drinkers = require("../models/drinkers.model") in the sodasController
The Drinkers model:
const Schema = mongoose.Schema;
const drinkersSchema = new Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
sodas: {
type: Schema.Types.ObjectId,
ref: "Sodas",
},
},
{ timestamps: true }
);
The Sodas model
const Schema = mongoose.Schema;
const sodaSchema = new Schema(
{
name: {
type: String,
required: true,
},
drinker: {
type: Schema.Types.ObjectId,
ref: "Drinkers",
},
},
{ timestamps: true }
);
I would add a middleware function which validates if the drinkerId exists. If it exists, you can continue to the controller. If not, then you should throw a 404 error.
Your route:
router.get(
'/all/:drinkerId',
drinkerMiddleware.exists,
sodasController.getAllSodasFromDrinker
);
drinkerMiddleware:
exports.exists = async (req, res, next) => {
try {
const drinker await Drinker.find({ drinker: req.params.drinkerId }).exec();
if (!drinker) {
return next("Drinker not found.");
}
return next();
} catch (error) {
return next(error);
}
};