EXPRESS GET info on user - node.js

Hello I want to be able to pass a user into a get request to see what items they have posted.
Here is the GET request
// #route GET with NAME
// #desc GET All ITEMS WITH NAME
// #access private
router.get('/:user', (req, res) => {
Item.findBy(req.params.user)
.sort({ date: -1})
.then(items => res.json(items))
});
Then I want to be able to pass it through the actions file.
export const getItems = () => dispatch => {
dispatch(setItemsLoading());
axios.get(`/api/items/`).then(res =>
dispatch({
type: GET_ITEMS,
payload: res.data
})
)
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
}
Here is the item modal if anyone was wondering
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//Create Schema
const ItemSchema = new Schema({
name:{
type: String,
required: true
},
user:{
type: String,
required: true
},
date:{
type: Date,
default: Date.now
}
});
module.exports = Item = mongoose.model('item', ItemSchema);
The expected results of this would be
http://localhost:3000/{username}
Product list
"name":"Item name"
"date": "mm/dd/yy"
I am also new to mongoDB/Json. I am coming from using SQL.

In this case I would use req.query.user and the url would be http://localhost:3000/?username.
Then in router.get method pull the correct db data from mongoDB and res.send data to client.

Related

trying to post my blog collection to mongoDB

i'm new to nodeJS. am trying a use post request to get the information the user post but am getting an error: TypeError: Cannot read properties of undefined (reading 'title'). please what am i doing wrong here.
here's my code
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
const BlogPost = new Schema({
title:{
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
app.post("/blogs", (req, res) => {
const blogs = new Blog({
title:req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
To make this code to workable condition for that add app.use(express.json())
As we are accepting http request body value from postman , so that it will parse our http request into json payload,
Hence we can access the body parameters value by req.body..
const express = require("express")
const app = express()
const mongoose = require("mongoose")
const Schema = mongoose.Schema;
// 2 json parsing
app.use(express.json())
//as my mongoose version is latest one so in that strictQuery is not supported
mongoose.set('strictQuery', false);
const BlogPost = new Schema({
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
body: {
type: String,
required: true
}
})
const Blog = mongoose.model("Blog", BlogPost)
module.exports = Blog;
//3. connection bridge between applicaion and mongoose
const connectionUrl = 'mongodb://127.0.0.1:27017'
mongoose.connect(connectionUrl, {
useNewUrlParser: true
},()=>{
console.log('Connected to MongoDB')
})
//Middleware
app.post("/blogs", (req, res) => {
//console.log(req.body.title+ " "+ req.body.content+ " "+ req.body.body );
const blogs = new Blog({
title: req.body.title,
content: req.body.content,
body: req.body.body,
})
blogs.save()
.then(result => console.log(result))
.catch(err => console.log(err))
})
// 1.listen
app.listen(3033, () => {
console.log("Server is running on port 3033")
});
/**
* use post request to get the information
* the user post but getting an error:
* TypeError: Cannot read properties of undefined (reading 'title').
*/
enter image description here
enter image description here
You may not get title from req.body.title that's why when you save this doc to mongodb it will throw this error.
For solution, you must check req.body.title before saving data into mongodb,
Otherwise, simply REMOVE required: true from schema
title:{
type: String,
required: true
},

How to search in mongoDB if an element is in an array

I'm creating the backend of my project. In this project, there are some groups, and each groups has its partecipant. I would like to make a function in nodejs that retrive all the groups that, in the partecipant field(which is an array), has a given user.
Here is the schema of group:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const GroupSchema = new Schema({
name: {
type: String,
required: true,
unique: true,
},founder:{
type:String,
required: true,
}, partecipants:{
type: Array,
required:false,
}, files: {
type:Array,
required: false,
}
})
const Group = mongoose.model('Group', GroupSchema);
module.exports = Group;
For now, I wrote only this:
const getGroupByUser = (req, res) => {
const user = req.body.user;
Group.find()
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
But it obviusly returns all the groups. I don't know if there is a way to make it in the promise, or if I have to cycle throught the array, like a linear search, but for multiple cases. Any idea? Thank you
const getGroupByUser = (req, res) => {
const user = req.body.user;
const id = req.query.id;
// if id is saved as objectId covert it using Types.ObjectId(id)
Group.find({partecipants: id})
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
using {partecipants: id} you tell to mongoDb to find all group that have into the array the userId you pass in query params

how to reference a model in another model using mongoose?

I'm pretty new to node and mongoose, still learning a lot. Basically I am trying to create a forum page. I have a forumpost schema and I have recently added in a new field that I would like to show which user posted it. I have read other questions on this online and I was able to follow the code on there however mine is still not working. When i check my data in atlas it is still missing the new 'submitted by' field that I added. I have already deleted the 'collection' and have started over but it is still missing. Any help would be appreciated. Heres my models below as well as a screencap of how the data is being posted to the db.
**Post Form Schema**
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
required: true,
},
submittedBy: { *(this is where I would like to get the user who submitted the form)*
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
extraInfo: {
type: String,
default: 'Other info goes here',
}
})
const Post = mongoose.model('Post', PostSchema);
module.exports = Post;
**Users Form Schema**
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
EDIT: heres my newpost route
const express = require('express');
const Post = require('../models/post');
const router = express.Router();
const {ensureAuthenticated} = require("../config/auth.js");
router.get('/', ensureAuthenticated, (req, res) => {
res.render('newPost')
})
router.post('/', ensureAuthenticated, (req, res) => {
const post = new Post(req.body);
console.log(req.body)
post.save()
.then((result) => {
res.redirect('/dashboard')
})
.catch((err) => {
console.log(err)
})
})
module.exports = router;
If I'm not mistaken, you validate if is authenticated with the "ensureAuthenticated" middleware (the user ID should be there) but when creating the "Post" you only do it with the body data.
It is something like this ( you should replace "userId" with your property name):
const post = new Post({ ...req.body, submittedBy: userId })

mongoose populate in array of custom objects

In the user model, I have an array of custom objects followedPlaylists which contains two attributes ( playlist: the id of the playlist, public: to determine whether it is public or not) as shown below
const userSchema = new mongoose.Schema({
..... other attributes
followedPlaylists: [{
playlist: {
type: mongoose.Schema.ObjectId,
ref: 'Playlist',
unique: true
},
public: Boolean
}]
})
I want to populate on followedPlaylists.playlist so the response would be something like
[{
playlist: * the actual playlist object *,
public: true
}]
I hope my question is clear enough and thanks in advance.
Here I am assuming that your Playlist is working just fine. i.e., it has elements and has been tested independently.
So, given the schema:
Const Playlist = require (./Playlist)//here you have to provide the path to the Playlist model or use mongoose.model (“Playlist”) to bring it in
………….
const userSchema = new mongoose.Schema({
..... other attributes
followedPlaylists: [{
playlist: {
type: mongoose.Schema.ObjectId,
ref: 'Playlist',
unique: true
},
public: Boolean
}]
})
On whatever you want to print it, just make something like:
Const user = mongoose.model (“User”);//or use require, what fits best your applications
……
Console.log(user.find().populate(“Playlist”))//here is the trick, you ask to populate the Playlist
Example
Examples are the best way to grasp a concept. You can play around with this example:
//------------------------------------------------------------------
const mongoose = require("mongoose");
const { model, Schema } = require("mongoose");
var dbURI = "mongodb://localhost/mongoose-sample";
const app = require("express")();
mongoose
.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(console.log(`connected to ${dbURI}`));
//----------------------------------------------------------------------
const departmentSchema = new Schema({ name: String, location: String });
const Department = model("department", departmentSchema);
const EmployeeSchema = new Schema({
firstName: String,
lastName: String,
department: { type: mongoose.Types.ObjectId, ref: "department" }
});
const Employee = model("employee", EmployeeSchema);
app.use("/", async (req, res) => {
// await Department.remove({});
// await Department.create({
// name: "Fiocruz",
// location: "Presidência"
// }).then(console.log(`we are good`));
// await Department.create({
// name: "IASI",
// location: "Roma"
// }).then(console.log(`we are good`));
// await Employee.create({
// firstName: "Jorge",
// lastName: "Pires",
// department: await Department.findOne({ name: "Fiocruz" })
// });
// await Employee.create({
// firstName: "Marcelo",
// lastName: "Pires",
// department: await Department.findOne({ name: "IASI" })
// });
// Employee.findOne("")
// .populate("department", "name")
// .select("department")
// .then(result => {
// console.log(result);
// });
await Employee.findOne({ _id: "5e6e28ec480a9d32fc78c46b" }, (err, result) => {
console.log(result);
})
.populate("department", "name")
.select("department");
res.json({
departments: await Department.find(),
employees: await Employee.find(),
employeesWithDep: await Employee.find().populate("department", "name"),
justDepartment: await Employee.findOne({ _id: "5e6e28ec480a9d32fc78c46b" })
.populate("department", "name")
.select("department")
});
});
app.listen(3000, () => {
console.log("we are on port 3000");
});

Implement follow/unfollow like action using Node + Express.js and MongoDB

I'm trying to design a Twitter style API. I've come up with the following Schema:
User collection
username
password
Followers collection
follower_id
followee_id
start_date
end_date
Eg:
{
follower_id: 1235
followee_id: 1024
start_date: November 3, 2018
}
which means user 1024 follows user 1235.
Absence of end_date indicates that the user is still following.
Tweets collection
text
date_created
user_id
user_id will be a reference to User collection.
How can I achieve follow/unfollow action with above schema?
For the user collection, you could have a following[] array. As in, you put each user id that they are following in the array and then remove it when they unfollow a person. Then with express, you can handle a post request sent by the front end with express. Of course you would need a boolean to say like:
// To show the button saying "follow" or "unfollow"
var followingArray = [123414, 312456, 656465];
var following = false;
if (followingArray.indexOf(userid)) {
following = true;
} else {
following = false;
}
Obviously, this is just a concept and you would need other code from mongoose or the regular mongodb module to get the user id. This would also decide whether or not the post request link is going to be http://myapp.com/follow or http://myapp.com/unfollow. Based on these two post requests, you would handle the data like the user id with body-parser and express:
var bodyParser = require('body-parser');
const express = require('express');
const app = express();
const port = 8080
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.post('/follow', (req, res) => {
//handle data here for a request to follow someone
var userid = req.body.userid;
})
app.post('/unfollow', (req, res) => {
//handle data here for a request to unfollow someone
var userid = req.body.userid
})
app.listen(port, () => {
console.log(`Server running on ${port}`);
})
Then you would use this data with mongoose or the mongodb module to remove or add that user id from the array and change the following boolean to true or false. Then if you wanted to add other features like a followers list or a following list, you could use the user id to do so. I am not giving exact code on how to do this as there are many concepts involved. I am just trying to give you the concepts that you would use in doing so.
I recommend this:
Keep the database as "flat" as possible. That means fewer collections.
You'd probably need only 2 collections: users and tweets
In your users schema should look something like this:
// Asuming you use mongoose, if you haven't heard about it, you should look it up.
const userSchema = new Schema({
username: {type: String, required: true, trim: true},
password: {type: String, required: true},
following: {type: Array}, // Store all user id of the people that this user is following in an array.
followers: {type: Array}, // Store all users id of this user's followers in an array.
tweets: {
type: Schema.Types.ObjectId, // Store all tweets by this user in an object.
ref: "Tweet" // Link to Tweet Schema
}
}, {_id: true});
Your tweets schema:
const tweetSchema = new Schema({
text: {type: String, required: true}
// You can also have a userId to store the id of the user whose this tweet belongs to
}, {_id: true});
You then can use create to create users or tweets, update to edit following or followers.
Obviously there are several ways to achieve what you want. This is just one of them.
Following Solution Works for me:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
},
following: {
type: Array
},
followers: {
type: Array
},
},
{
timestamps: true,
}
);
const User = mongoose.model("User", userSchema);
module.exports = User;
router.patch("/api/v1/follow/", auth, async (req, res) => {
try {
let whomFollowed = await User.findByIdAndUpdate({ _id: req.body.followingId},
{ $push: { following: req.body.followerId } }
);
let whoFollowedMe = await User.findByIdAndUpdate({ _id: req.body.followerId },
{ $push: { followers: req.body.followingId } }
)
return res.status(200).send({ message: "User Follow Success"});
} catch (e) {
return res.status(500).send({ message: "User Follow Failed", data: e.message });
}
});
router.patch("/api/v1/unfollow/", auth, async (req, res) => {
try {
let whomUnFollowed = await User.findByIdAndUpdate({ _id: req.body.followingId },
{ $pull: { following: req.body.followerId } }
);
let whoUnFollowedMe = await User.findByIdAndUpdate({ _id: req.body.followerId },
{ $pull: { followers: req.body.followingId } }
)
return res.status(200).send({ message: "User UnFollow Success"});
} catch (e) {
return res.status(500).send({ message: "User UnFollow Failed", data: e.message });
}
});

Resources