Storing questions to an array of data - javascript

I've been trying to figure out how to add comments to an array of data in my local db. The idea I'm working on now is to add the array of comments to the array of data so it's easy to know which comment is for which set of data. When I try to do so using the following code, it won't work:
(This is in the userschema where I define the array that will hold the data)
test1: { type: array, required: false }
(Next I try to add the comment array with push but it won't work, I'm using test 0 as an example normally it will depend on what test you'd like to add your comments to. Test1 consists in turn of more arrays with the data in question to which I want to add the comments. Which is why I use user.test1[0])
user.test1[0].push(newComment);
(That does not work while the following does using splice)
user.test1.splice(1, 0, newComment)
For some reason it seems like a can't access the user.test1[0] but I have no idea why? Or should I use another technique when it comes to adding comments to a test?
app.updateTest1 = function(newComment1, newComment2, index) {
app.errorMsg = false; // Clear any error message
app.disabled = true; // Lock form while processing
// Check if username submitted is valid
var userObject = {}; // Create the user object to pass to function
userObject._id = app.currentUser; // Pass current user _id in order to edit
userObject.test1 = [$scope.newComment1, $scope.newComment2];
User.editUser(userObject).then(function(data) {
});
};
userFactory.editUser = function(id) {
return $http.put('/api/edit', id);
};
router.put('/edit', function(req, res) {
var editUser = req.body._id; // Assign _id from user to be editted to a variable
if (req.body.name) var newName = req.body.name; // Check if a change to name was requested
if (req.body.username) var newUsername = req.body.username; // Check if a change to username was requested
if (req.body.email) var newEmail = req.body.email; // Check if a change to e-mail was requested
if (req.body.permission) var newPermission = req.body.permission; // Check if a change to permission was requested
if (req.body.test1) {
var newTest1 = req.body.test1;
}
if (req.body.test2) {
var firstTest2 = req.body.test2;
var newTest2 = firstTest2.split(" ");
}
if (req.body.test3) {
var firstTest3 = req.body.test3;
var newTest3 = firstTest3.split(" ");
}
if (req.body.test4) {
var firstTest4 = req.body.test4;
var newTest4 = firstTest4.split(" ");
}
if (req.body.test5) {
var firstTest5 = req.body.test5;
var newTest5 = firstTest5.split(" ");
}
// Look for logged in user in database to check if have appropriate access
User.findOne({ username: req.decoded.username }, function(err, mainUser) {
if (err) {
// Create an e-mail object that contains the error. Set to automatically send it to myself for troubleshooting.
var email = {
from: 'MEAN Stack Staff, cruiserweights#zoho.com',
to: 'gugui3z24#gmail.com',
subject: 'Error Logged',
text: 'The following error has been reported in the MEAN Stack Application: ' + err,
html: 'The following error has been reported in the MEAN Stack Application:<br><br>' + err
};
// Function to send e-mail to myself
client.sendMail(email, function(err, info) {
if (err) {
console.log(err); // If error with sending e-mail, log to console/terminal
} else {
console.log(info); // Log success message to console if sent
console.log(user.email); // Display e-mail that it was sent to
}
});
res.json({ success: false, message: 'Something went wrong. This error has been logged and will be addressed by our staff. We apologize for this inconvenience!' });
} else {
// Check if logged in user is found in database
if (!mainUser) {
res.json({ success: false, message: "no user found" }); // Return error
} else {
// Check if a change to name was requested
if (newName) {
// Check if person making changes has appropriate access
if (mainUser.permission === 'admin' || mainUser.permission === 'moderator') {
// Look for user in database
User.findOne({ _id: editUser }, function(err, user) {
if (err) {
// Create an e-mail object that contains the error. Set to automatically send it to myself for troubleshooting.
var email = {
from: 'MEAN Stack Staff, cruiserweights#zoho.com',
to: 'gugui3z24#gmail.com',
subject: 'Error Logged',
text: 'The following error has been reported in the MEAN Stack Application: ' + err,
html: 'The following error has been reported in the MEAN Stack Application:<br><br>' + err
};
// Function to send e-mail to myself
client.sendMail(email, function(err, info) {
if (err) {
console.log(err); // If error with sending e-mail, log to console/terminal
} else {
console.log(info); // Log success message to console if sent
console.log(user.email); // Display e-mail that it was sent to
}
});
res.json({ success: false, message: 'Something went wrong. This error has been logged and will be addressed by our staff. We apologize for this inconvenience!' });
} else {
// Check if user is in database
if (!user) {
res.json({ success: false, message: 'No user found' }); // Return error
} else {
user.name = newName; // Assign new name to user in database
// Save changes
user.save(function(err) {
if (err) {
console.log(err); // Log any errors to the console
} else {
res.json({ success: true, message: 'Name has been updated!' }); // Return success message
}
});
}
}
});
} else {
res.json({ success: false, message: 'Insufficient Permissions' }); // Return error
}
}
if (newTest1) {
// Check if person making changes has appropriate access
if (mainUser.permission === 'admin') {
// Look for user in database
User.findOne({ _id: editUser }, function(err, user) {
if (err) {
res.json({ success: false, message: 'Something went wrong. This error has been logged and will be addressed by our staff. We apologize for this inconvenience!' });
} else {
// Check if user is in database
if (!user) {
res.json({ success: false, message: 'No user found' }); // Return error
} else {
-> (this is where i think the problem is) if (Array.isArray(newTest1)) {
var index = newTest1[2];
-> this doesn't work user.test1[0].push(newTest1);
//user.test1.splice(index, 0, newTest1)
} else {
var testet1 = newTest1.split(" ");
user.test1.push(testet1); // Assign new name to user in database
}
// Save changes
user.save(function(err) {
if (err) {
console.log(err); // Log any errors to the console
} else {
res.json({ success: true, message: 'Name has been updated!' }); // Return success message
}
});
}
}
});
} else {
res.json({ success: false, message: 'Insufficient Permissions' }); // Return error
}
}

You need to make sure user.test1[0] value exists before manipulating it. So if your user.test1
var user = {};
user.test = [];
var arrayToPush = [1,2,3];
try {
user.test[0].push(arrayToPush)
} catch (err) {
document.getElementById('out').innerHTML += err
}
var user2 ={}
user2.test=[];
try {
user2.test.push(arrayToPush)
user2.test.push(arrayToPush)
} catch (err) {
document.getElementById('out2').innerHTML += err
}
document.getElementById('out2').innerHTML += user2.test[0]
<div id="out"></div>
<br>
<div id="out2"></div>
array has no values at all you can't push to it anything.

Related

ExpressJS variable undefined

I have an ExpressJS app that when a user makes a POST request to a route, it should lookup the ID in the MongoDB using req.params.formId
I have some console.log statements tfor debugging and so I can see what info is being returned.
The route should lookup the ID passed and when it finds it, use the req.body data and also a field from the MongoDB document but this just seems to return as undefined
Here is the code for the route:
app.post("/api/v1/forms/:formId", (req, res) => {
const { name, email, message } = req.body;
console.log(req.body);
Form.findById(req.params.formId, Form.recipient, err => {
if (err) {
res.send(err);
} else {
const formRecipient = Form.recipient;
const newForm = {
name,
email,
message,
recipient: formRecipient
};
console.log(newForm);
const mailer = new Mailer(newForm, contactFormTemplate(newForm));
try {
mailer.send();
res.send(req.body);
} catch (err) {
res.send(err);
}
}
});
});
So an example, if I make a POST request to localhost:5000/api/v1/forms/5ad90544883a6e34ec738c19 the console.log of newForm shows { name: ' Mr Tester',
email: 'person#example.com',
message: 'Hi there',
recipient: undefined }
The forms Mongoose schema has a field named recipient
the correct way is to provide the fields you want to get as the second argument:
Form.findById(req.params.formId, 'recipient', (err, form) => {
if (err) {
// error handling code
} else {
const formRecipient = form.recipient;
}
...
});
here's the Docs

API call does not work on Angular 4. No 'Access-Control-Allow-Origin' header, 400

I have problem in ticket sistem. The post ticket is work but comment ticket does not work.
Erro:
Failed to load http://localhost:3977/api/tickets/comment: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 400.
Follow Code:
Frontend:
// Function to create new ticket form
createNewTicketForm() {
this.form = this.formBuilder.group({
// Title field
title: ['', Validators.compose([
Validators.required,
Validators.maxLength(50),
Validators.minLength(5),
this.alphaNumericValidation
])],
// Body field
body: ['', Validators.compose([
Validators.required,
Validators.maxLength(500),
Validators.minLength(5)
])]
})
}
// Create form for posting comments
createCommentForm() {
this.commentForm = this.formBuilder.group({
comment: ['', Validators.compose([
Validators.required,
Validators.minLength(1),
Validators.maxLength(200)
])]
})
}
// Enable the comment form
enableCommentForm() {
this.commentForm.get('comment').enable(); // Enable comment field
}
// Disable the comment form
disableCommentForm() {
this.commentForm.get('comment').disable(); // Disable comment field
}
// Enable new ticket form
enableFormNewTicketForm() {
this.form.get('title').enable(); // Enable title field
this.form.get('body').enable(); // Enable body field
}
// Disable new ticket form
disableFormNewTicketForm() {
this.form.get('title').disable(); // Disable title field
this.form.get('body').disable(); // Disable body field
}
// Validation for title
alphaNumericValidation(controls) {
const regExp = new RegExp(/^[a-zA-Z0-9 ]+$/); // Regular expression to perform test
// Check if test returns false or true
if (regExp.test(controls.value)) {
return null; // Return valid
} else {
return { 'alphaNumericValidation': true } // Return error in validation
}
}
// Function to display new ticket form
newTicketForm() {
this.newPost = true; // Show new ticket form
}
// Reload tickets on current page
reloadTickets() {
this.loadingTickets = true; // Used to lock button
this.getTickets(); // Add any new tickets to the page
setTimeout(() => {
this.loadingTickets = false; // Release button lock after four seconds
}, 4000);
}
// Function to post a new comment on ticket post
draftComment(id) {
this.commentForm.reset(); // Reset the comment form each time users starts a new comment
this.newComment = []; // Clear array so only one post can be commented on at a time
this.newComment.push(id); // Add the post that is being commented on to the array
}
// Function to submit a new ticket post
onTicketSubmit() {
this.processing = true; // Disable submit button
this.disableFormNewTicketForm(); // Lock form
// Create ticket object from form fields
const ticket = {
title: this.form.get('title').value, // Title field
body: this.form.get('body').value, // Body field
createdBy: this.username // CreatedBy field
}
// Function to save ticket into database
this._ticketService.newTicket(this.token, ticket ).subscribe(data => {
// Check if ticket was saved to database or not
if (!data.success) {
this.messageClass = 'alert alert-danger'; // Return error class
this.message = data.message; // Return error message
this.processing = false; // Enable submit button
this.enableFormNewTicketForm(); // Enable form
} else {
this.messageClass = 'alert alert-success'; // Return success class
this.message = data.message; // Return success message
this.getTickets();
// Clear form data after two seconds
setTimeout(() => {
this.newPost = false; // Hide form
this.processing = false; // Enable submit button
this.message = false; // Erase error/success message
this.form.reset(); // Reset all form fields
this.enableFormNewTicketForm(); // Enable the form fields
}, 2000);
}
});
}
// Function to go back to previous page
goBack() {
window.location.reload(); // Clear all variable states
}
// Function to get all tickets from the database
getTickets() {
// Function to GET all tickets from database
this._ticketService.getTickets(this.token).subscribe(data => {
this.ticketPosts = data.tickets; // Assign array to use in HTML
});
}
// Function to post a new comment
postComment(id) {
this.disableCommentForm(); // Disable form while saving comment to database
this.processing = true; // Lock buttons while saving comment to database
const comment = this.commentForm.get('comment').value; // Get the comment value to pass to service function
// Function to save the comment to the database
this._ticketService.postComment(this.token, comment).subscribe(data => {
this.getTickets(); // Refresh all tickets to reflect the new comment
const index = this.newComment.indexOf(id); // Get the index of the ticket id to remove from array
this.newComment.splice(index, 1); // Remove id from the array
this.enableCommentForm(); // Re-enable the form
this.commentForm.reset(); // Reset the comment form
this.processing = false; // Unlock buttons on comment form
if (this.enabledComments.indexOf(id) < 0) this.expand(id); // Expand comments for user on comment submission
});
}
Backend:
function saveTicket(req, res){
if (!req.body.title) {
res.json({ success: false, message: 'Ticket title is required.' }); // Return error message
} else {
// Check if ticket body was provided
if (!req.body.body) {
res.json({ success: false, message: 'Ticket body is required.' }); // Return error message
} else {
// Create the ticket object for insertion into database
const ticket = new Ticket({
title: req.body.title, // Title field
body: req.body.body, // Body field
createdBy: req.body.createdBy // CreatedBy field
});
ticket.save((err, ticketStored) => {
// Check if error
if (err) {
// Check if error is a validation error
if (err.errors) {
// Check if validation error is in the title field
if (err.errors.title) {
res.json({ success: false, message: err.errors.title.message }); // Return error message
} else {
// Check if validation error is in the body field
if (err.errors.body) {
res.json({ success: false, message: err.errors.body.message }); // Return error message
} else {
res.json({ success: false, message: err }); // Return general error message
}
}
} else {
res.json({ success: false, message: err }); // Return general error message
}
} else {
res.json({ success: true, message: 'Ticket Salvo' }); // Return success message
}
});
}
}
};
function saveComment(req, res){
// Check if comment was provided in request body
if (!req.body.comment) {
res.json({ success: false, message: 'No comment provided' }); // Return error message
} else {
// Check if id was provided in request body
if (!req.body.id) {
res.json({ success: false, message: 'No id was provided' }); // Return error message
} else {
// Use id to search for ticket post in database
Ticket.findOne({ _id: req.body.id }, (err, ticket) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Invalid ticket id' }); // Return error message
} else {
// Check if id matched the id of any ticket post in the database
if (!ticket) {
res.json({ success: false, message: 'Ticket not found.' }); // Return error message
} else {
// Grab data of user that is logged in
User.findOne({ _id: req.decoded.userId }, (err, user) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Something went wrong' }); // Return error message
} else {
// Check if user was found in the database
if (!user) {
res.json({ success: false, message: 'User not found.' }); // Return error message
} else {
// Add the new comment to the ticket post's array
ticket.comments.push({
comment: req.body.comment, // Comment field
commentator: user.username // Person who commented
});
// Save ticket post
ticket.save((err, ticketStored) => {
// Check if error was found
if (err) {
res.json({ success: false, message: 'Something went wrong.' }); // Return error message
} else {
res.json({ success: true, message: 'Comment saved' }); // Return success message
}
});
}
}
});
}
}
});
}
}
};
Routes:
api.post('/ticket', md_auth.ensureAuth, TicketController.saveTicket);
api.post('/tickets/comment/', md_auth.ensureAuth, TicketController.saveComment);
Someone give me help?
Ragards, Santana Marcos
Looks like a common CORS issue. If you are using Angular CLI (and I guess it's so), then you probably need to configure proxy for api-requests from dev-server 4200 port to api-server 3977 port. The official doc is here. Follow it and create appropriate config file and set --proxy-config option to the npm ng serve script:
proxy.conf.json
{
"/api": {
"target": "http://localhost:3977",
"secure": false
}
}
package.json
"start": "ng serve --proxy-config proxy.conf.json"
The requests form your front end (TicketService) should be like following
this.http.post('/api/tickets/comment', ...
And the handling on the back end
api.post('/api/tickets/comment', ...

401 - unauthorized access : Auth0 and azure

I have connected my Database to auth0 and when I try the connection is returns 401 unauthorized access. I have allowed auth into my firewall and the password is correct. How come it is returning this error when searching for username and password?
More info
in my easy tables I made them authenticated access only, do I have to do something to get around this?
function login(email, password, callback) {
//this example uses the "tedious" library
//more info here: http://pekim.github.io/tedious/index.html
var Connection = require('tedious#1.11.0').Connection;
var Request = require('tedious#1.11.0').Request;
var TYPES = require('tedious#1.11.0').TYPES;
var connection = new Connection({
userName: 'username',
password: 'pass',
server: 'server',
options: {
database: 'db',
encrypt: true,
rowCollectionOnRequestCompletion: true
}
});
var query = "SELECT Id, Email, Password " +
"FROM user WHERE Email = #Email";
connection.on('debug', function (text) {
// Uncomment next line in order to enable debugging messages
// console.log(text);
}).on('errorMessage', function (text) {
console.log(JSON.stringify(text, null, 2));
return callback(text);
}).on('infoMessage', function (text) {
// Uncomment next line in order to enable information messages
// console.log(JSON.stringify(text, null, 2));
});
connection.on('connect', function (err) {
if (err) { return callback(err); }
var request = new Request(query, function (err, rowCount, rows) {
if (err) {
callback(new Error(err));
} else if (rowCount < 1) {
callback(new WrongUsernameOrPasswordError(email));
} else {
bcrypt.compare(password, rows[0][2].value, function (err, isValid) {
if (err) { callback(new Error(err)); }
else if (!isValid) { callback(new WrongUsernameOrPasswordError(email)); }
else {
callback(null, {
user_id: rows[0][0].value,
email: rows[0][1].value
});
}
});
}
});
request.addParameter('Email', TYPES.VarChar, email);
connection.execSql(request);
});
}
Since you are using Azure Mobile App, which included the Node.js server SDK for your app. Then you don't need to install tedious to work with Azure SQL database. The SDK has already wrapped up mssql to do this. So basically you can use this code sample to connect your database.
var api = {
// an example of executing a SQL statement directly
get: (request, response, next) => {
var query = {
sql: 'UPDATE TodoItem SET complete = #completed',
parameters: [
{ name: 'completed', value: request.query.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
},
// an example of executing a stored procedure
post: (request, response, next) => {
var query = {
sql: 'EXEC completeAllStoredProcedure #completed',
parameters: [
{ name: 'completed', value: request.query.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
}
};
module.exports = api;
For more information, please refer to this documentation.

How To Use Variables Down A Promise Chain

I am using nodejs with express framework and mongodb/mongoose to store my data.
I have a register function which does 4 things. Creates a user, creates a token, assigns the token to the user and finally sends an email.
I initially did this using callbacks which worked fine. Im trying to use promises now i have required bluebird to do this. However when one promise is complete i need to use that returned variable in the next promise.
Register Function
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
var promise = newUser.save();
promise.then(function(user) {
return createToken('new', null, user._id);
}).then(function(token) {
user.tokens.push(token._id);
return user.save();
}).then(function(user) {
//Do Email Stuff
}).catch(function(err) {
return res.json("Could Not Register");
});
}
Create Token Function
var createToken = function(type, expiry, userid) {
var token = uuid.v4();
return new Promise(function(resolve, reject) {
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: userid
});
var promise = newToken.save();
promise.then(function(token) {
resolve(token);
}).catch(function(err) {
reject(err);
});
});
};
So where im doing "user.tokens.push" it can't find the user. ive read in bluebird that i can use somethign called binding? and then use "this". Could anyone show me how to do this properly.
Also if there is an an error in each promise i'd like the catch method to be dynamic. Instead of just "Could not register" it would be "Could Not Save User" or "Could Not Save Token" depending on which promise failed.
And if theres a way to make this even cleaner let me know.
there's no shame in using a var in the scope of the register function to store the value of user for later use
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
var sUser; // store user in this var
newUser.save()
.then(function(user) {
sUser = user; // save value user to use later on
return createToken('new', null, user._id);
}).then(function(token) {
sUser.tokens.push(token._id); // sUser is user, huzzah
return sUser.save();
}).then(function(user) {
//Do Email Stuff
}).catch(function(err) {
// use the content of err to return a meaningful error
return res.json("something more meaningful based on the content of err");
});
}
You should also avoid the new Promise antipattern in createToken
var createToken = function(type, expiry, userid) {
var token = uuid.v4();
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: userid
});
return newToken.save();
};
That produces an identical result to your code
another way would be to send user to the createToken function and rewrite your code like this
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
newUser.save()
.then(function(user) {
return createToken('new', null, user);
}, function(err) { // optionally change errors to meaningful error messages
throw "newUser.save failed";
}).then(function(user) {
//Do Email Stuff
// you could throw "email failed" if there's an error
}).catch(function(err) {
// err could be "newUser.save failed", "newToken.save failed", "email failed"
// use the content of err to return a meaningful error
return res.json("something more meaningful based on the content of err");
});
}
var createToken = function(type, expiry, user) {
var token = uuid.v4();
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: user._id
});
return newToken.save()
.then(function(token) {
user.tokens.push(token._id);
return user.save();
}) // you could add the following to make the errors suited to you
.catch(function(err) {
throw "newToken.save failed";
});
};

Parse.com: getting UserCannotBeAlteredWithoutSessionError

I have an Angular service that takes in a roleId and userId and assigns the user to that role and make a pointer in User to that role.
app.service('CRUD', function () {
this.addUserToRole = function (roleId, userId) {
// first we have to find the role we're adding to
var query = new Parse.Query(Parse.Role);
return query.get(roleId, {
success: function (role) {
// then add the user to it
var Database = Parse.Object.extend("User");
var query = new Parse.Query(Database);
console.log(role);
return query.get(userId, {
success: function (user) {
console.log(user);
role.getUsers().add(user);
role.save();
// now we need to tell the user that he has this role
console.log(user);
user.attributes.role.add(role);
user.save();
return user;
},
error: function (err) {
return err;
}
});
},
error: function (err) {
console.log(err);
}
});
}
});
I'm getting {"code":206,"error":"Parse::UserCannotBeAlteredWithoutSessionError"} on user.save();
After some research, I arrived at this website. He uses this code snippet as a JS SDK example:
Parse.Cloud.run('modifyUser', { username: 'userA' }, {
success: function(status) {
// the user was updated successfully
},
error: function(error) {
// error
}
});
and mentions something about a useMasterKey() function.
I'm still unsure how to fix this error.
Add
Parse.Cloud.useMasterKey();
at the beginning of your function.
Set it up as a background job. That is the code snip you found I think and a simpler far more secure means of fondling users and roles
https://parse.com/docs/cloud_code_guide#jobs

Categories