React POST request without form? - javascript

I am trying to familiarize myself with sending POST data, this time using React. In this instance, I am attempting to do it without a form.
My front-end React code specifically looks like so:
stockconfirmbuy: function(){
var stin = this.refs.stockpriceref.innerHTML;
var totalbuyval = stin * this.state.stockdnum;
return (<div>
<p>Are you sure you would like to buy {this.refs.stocknameref.innerHTML} stock at ${this.refs.stockpriceref.innerHTML} per share?</p>
<p>Select Amount:</p>
<input className="form-control" defaultValue="1" type="number" value={this.state.stockdum} onChange={this.changestocknum} />
<p>Your Total:</p>
<p>${totalbuyval}</p>
<div id="buttongroups">
<button className="btn btn-success" onClick={this.buyprocess}>Buy It</button>
<button className="btn btn-danger" onClick={this.cancelprocess}>Cancel</button>
</div>
</div>);
},
My initial stockdnum state value is 1, for clarity's sake.
Meanwhile, my schema is arranged like so:
var UserSchema = new Schema({
email: { type: String, unique: true, lowercase: true},
password: String,
icapital: {type: Number, default: 9001},
profile: {
name: { type: String, default: ''},
picture: { type: String, default: ''}
},
address: String,
history: [{
date: Date,
stocklabel: String,
stockname: String,
stocknumber: Number,
stockpaid: Number
}]
});
My attempt at coding the transaction into my routes/user.js page looks like so:
router.post('/profile', function(req, res, next) {
User.findOne({ _id: req.user._id }, function(err, user) {
if (err) return next(err);
if (req.body.stocklabel) user.history.stocklabel = req.body.stocklabel;
if (req.body.stockname) user.history.stockname = req.body.stockname;
user.history.date = Date();
if (req.body.stocknumber) user.history.stocknumber = req.body.stocknumber;
if (req.body.stockprice) user.history.stockprice = req.body.stockprice;
user.save(function(err) {
if (err) return next(err);
req.flash('success', 'Purchase sucessful');
return res.redirect('/profile');
});
});
});
First, I would like to make sure that my transaction lines up with the arrangement of my Schema.
Second, going back to my front-end React code, I am not sure how to take the relevant data from my React into my DB. I want the operation to run on {this.buyprocess}. However, since it is not a traditional input form, I am unsure how to turn it into a submit button that transfers these following pieces of info.
{this.refs.stockpriceref.innerHTML} repressents the stock label.
{this.state.stockdnum} represents the amount, or the stock number.
{totalbuyval} represents the total cost, or the stock price.
I am not sure what the code in the this.buyprocess function would look like.

Related

Friend Request System - Express, MongoDB, EJS

I want to create a social network thus allowing users to send and interact with frind requests. As of now I have created the register, log-in and "search for other users function".
When I find and select another user, I display their user-info and have created a "Add friend" button.
Can anyone help me in a direction of the creation of the "Add friend" option? I have looked around for some time now, and not been able to find the correct solution. Below I have attached my UserSchema and route for finding users:
//User Schema
const UserSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
password: {
type: String,
required: true
},
},{ collection: 'Users' });
//Get single user based on ID
router.get('/user/get:id', ensureAuthenticated, function (req, res) {
MongoClient.connect(DBUri,{useUnifiedTopology: true }, function (err, db) {
let dbo = db.db(DBName);
const query = {_id: objectId(req.params.id)}
dbo.collection("Users").find(query).toArray(function(err, resultTasks) {
if (err) throw err;
res.render('../View/findFriend', {
resultTasks: resultTasks
});
db.close();
});
});
});
You can add something like this in your user schema:
friends: [{ type : ObjectId, ref: 'User' }],
OR
friends: userSchema
Take the one which suits you.
What that will do is add an array to the user, Then you can store IDs of friends.(Who are other users, hence the ref: 'User')
Then, When you have to fetch users you can do:
User.find(<ID or whatever you have to find Users>).populate('friends')
Also, To push a new friend simply use: user.friends.push(newFriend._id)

mongodb: Deleting a user and all data references associated with it

Currently working on a personal website for myself and ran in to some difficulties with mongodb & mongoose when trying to delete a user.
Right now I have two Schema's show below.
UserSchema:
const userSchema = new mongoose.Schema({
username: {
type:String,
required: true,
unique: true,
},
password: String,
firstName: String,
lastName: String,
eMail: String,
status: {type:Boolean, default: true},
hobbies: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Hobby"
}
]
HobbySchema:
const hobbySchema = new mongoose.Schema({
title: String,
user: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
},
desc: String,
iconURL: String
});
My issue right now is that when I delete the user using the following route with nodeJS:
router.delete('/delete/:id', async (req,res) => {
await User.findOneAndDelete(req.params.id, (err, foundUser) => {
if(err){
console.log(err);
}else{
res.redirect("/logout");
}
})
});
I run into the issue that the Hobby collection still contains all hobbies that the user created. I'm looking to have them all deleted when the user wants to delete their account.I understand that Mongodb/Mongoose is a non-relation database and is unlike SQL as I'm coming from SQL. Is there any way to delete all hobbies a user created? (Just creating hobbies as a very basic example).
What is the best alternative? Just going with SQL lite and changing the database entirely?
Thanks

Dynamically pick values from req.body based on database attributes

I am building an app usine Node/EJS/Mongo where the user is building a capability survey, and needs to set the desired level for each question. The form that they use to pick the levels has a series of selects that look like:
<select class="form-control col-sm-4" id="<%=capability.capabilityId%>" name="<%=capability.capabilityId%>">
<option value=1>Developing</option>
<option value=2>Intermediate</option>
<option value=3>Advanced</option>
<option value=4>Role Model</option>
</select>
When the user then submits this form, I want to update the assessment to load in these expected levels.
The schema for assessments in my mongodb looks like:
var assessmentSchema = new mongoose.Schema ({
title: String,
startDate: Date,
endDate: Date,
behaviours: [{
behaviourName: String,
behaviourId: String,
order: Number,
capabilities: [{
orderCap: Number,
capabilityId: String,
capabilityName: String,
capabilityDesc: String,
developing: String,
intermediate: String,
advanced: String,
roleModel: String,
expectedLevel: Number,
motivation1: String,
motivation2: String,
motivation3: String,
motivation4: String,
motivation5: String
}] //capabilities object
}],
targetEmployees:[{
type: mongoose.Schema.Types.ObjectId,
ref: "Users"
}] //behaviours object
});
What I am thinking is I want to loop through all the capabilities, find the entry in req.body that has a name that matches capabilityId, and then update desiredLevel. I just can't see how to make it work. My route code currently looks like:
router.put(':id/levels', function(req, res) {
Assessment.findById(req.params.id, function(err, foundAssessment) {
foundAssessment.behaviours.forEach(function(b) {
b.capabilities.forEach(function(c) {
c.expectedLevel = req.body.SOMETHINGHERE
});
});
foundAssessment.save(function(err) {
if (err) {
console.log(err);
req.flash("error", err.message);
res.redirect("back");
} else {
// Send json back to xhr request
res.json(foundAssessment);
}
});
});
});
You can read request body dynamic attributes like this:
req.body[variable];

How to display users on current page?

For example I have a page with url "/foo", and I need to display my authenticated users nicknames on this page. Is there any default node.js/passport function for this, or I need to add every user of this page to database and display it with websockets?
User schema:
var userSchema = new Schema({
email: {type: String, required: true, unique: true },
password: {type: String, required: true },
nickname: { type: String, default: 'User'},
createdAt: { type: Date, default: Date.now }
});
Check if user is logged in:
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
req.session.oldUrl = req.url;
res.redirect('/');
}
This is how I solved it in a service that hosts stories. I had to display the number of users and their names on the current story page. I wanted to keep the solution simple enough so I decided to use a simple table in SQL.
In an SQL table with a single column, I stored PAGE_{PAGEID}_USER_{USERID}.
For every page when fetched by the user I added an entry on this table and queried the table column with the regex PAGE_{PAGEID}_USER_(.*) with updatedAt less than 1 minute of the current time.
This gives you the IDs of the users on the current page in the past 1 minute.
PS: The correct way to do this would be to do this very same thing in a Wide Column Store

mongoose document filtering properties

I have defined a schema like
var UserSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true },
location: { type: String, required: true },
picture: { type: String, required: true },
passwordHash: { type: String, required: true },
resetPasswordToken: String,
resetPasswordExpired: Boolean
});
I have a REST Endpoint which return list of all users. In that list I want to hide some properties i.e, passwordHash, resetPasswordToken, resetPasswordExpired
I defined a custom filter function like below
var doFilterUser = function(user) {
_.omit(user, ['passwordHash', 'resetPasswordToken', 'resetPasswordExpired']);
user.id = user._id;
delete user._id;
delete user.__v;
return user;
};
_ is lodash
When I check my API is responding with all user properties
This filter function is defined in common helper module and I am calling it like
User.findOne({_id: id}, function(err, user) {
var filtered = helper.doFilterUser(user);
});
How to resolve this issue?
Try this:
You are allowed to access certain values through mongoose.
User.findOne({_id: id}, 'firstName lastName email location picture', function(err, user){
console.log(user);
});
You just mention the fields needed, after the query.
Hope it helps....
The problem here is that you still have a mongoose document that conforms to s strict schema. If you want to change that document, then you need to make it a "raw" object without all the additional controls:
User.findOne({_id: id}, function(err, user) {
var filtered = helper.doFilterUser(user.toObject());
});
So the .toObject() method here will return an object in it's raw form. That allows you to manipulate the keys how you wish.
You can also explicitly direct it not to serve back certain properties. Useful if you don't want to render a hashed password over the wire. The find method would look like this:
User.find({}, '-id -__v',function(err,users){
})
or
User.findOne({_id: id}, '-id -__v',function(err,user){
})

Categories