Parsing nested data from select form with Angularjs - node.js

I'm trying to parse a model from a form which contain a select(ngOptions) and save it to db but the selected value is never parsed. i'm stuck here can someone help please.
here is my code:
View
<section class="container" data-ng-controller="TagsController" >
<h2><i class="fa fa-pencil-square-o"></i>Add a new Tag</h2>
<form class="form-horizontal col-md-5" data-ng-submit="create()">
<div class="form-group ">
<div class="controls">
<input type="text" class="form-control input-lg" data-ng-model="label" id="label" placeholder="Label" required>
</div>
</div>
<div class="form-group" data-ng-controller="CategoriesController" data-ng-init="find()">
<select class="form-control input-lg" ng-model="category._id" ng-options="category._id as category.label for category in categories">
<option value="">Choose a Category</option>
</select>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" class="btn">
</div>
</div>
</form>
</section>
controller
angular.module('mean.tags').controller('TagsController', ['$scope', '$routeParams', '$location', 'Global', 'Tags', function ($scope, $routeParams, $location, Global, Tags) {
$scope.global = Global;
$scope.create = function() {
var tag = new Tags({
label: this.label,
category: this.category
});
tag.$save(function(response) {
$location.path("tags/");
});
this.label = "";
this.category = "";
};
...

I found the problem so i will answer my question. The problem was due to architecture restrictions, Angularjs don't allow to nest a ng-controller inside an other one...

Related

CastError: Cast to ObjectId failed for value \"undefined\" (type string) at path \"_id\" for model \"students\""

So I have a problem in my CRUD application using Node JS, Express, and Mongo DB. Actually, I am just following this tutorial but I get stuck on the UPDATE part. I am able to CREATE, READ, and DELETE values from database already, but I don't know why I keep getting this error whenever I try to UPDATE my data.
I found the error is from my controller.js file and here's the code:
exports.update = (req,res)=>{
if(!req.body){
return res
.status(400)
.send({message:"Record to be updated can not be empty!"})
}
const id = req.params.id;
studentDb.findByIdAndUpdate(id,req.body,{userFindAndModify:false})
.then(data=>{
if(!data){
res.status(404).send({message:`Cannot update student record with ID ${id}. Maybe record not found.`})
}else{
res.send(data)
}
})
.catch(err=>{
res.status(500).send({message:`Error in updating student record with id=${id}.` + err})
})
}
My hypothesis is that the objectID goes on the first model in my schema because whenever I check the console when I run the application, the last value of the model in my schema, the "contact" goes undefined.
The ERROR:
I can provide the other codes related to this if my question is still unclear. Thank you in advance for answering! I've been stuck here for hours already.
EDIT
Here's the additional front-end code
(this is the FORM part from my update_student.ejs where I update the data):
<!-- form handling -->
<form method="POST" id="update_student">
<div class="new_student">
<div class="form-group">
<div class="row">
<div class="col-lg-4">
<label for="firstName" class="text-muted">First Name</label><br>
<input type="hidden" name="id" value="<%=students._id%>">
<input type="text" name="firstName" value="<%=students.firstName%>" placeholder="Corki">
</div>
<div class="col-lg-4">
<label for="middleName" class="text-muted">Middle Name</label><br>
<input type="text" name="middleName" value="<%=students.middleName%>" placeholder="Vi">
</div>
<div class="col-lg-4">
<label for="lastName" class="text-muted">Last Name</label><br>
<input type="text" name="lastName" value="<%=students.lastName%>" placeholder="Fortune">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-4">
<label for="gender" class="text-muted">Gender</label><br>
<div class="radio inline">
<input type="radio" id="radio-2" name="gender" value="Male" <% if(students.gender == "Male"){ %>checked <% } %>>
<label for="radio-2" class="radio-label">Male</label>
</div>
<div class="radio inline">
<input type="radio"id="radio-3" name="gender" value="Female" <% if(students.gender == "Female"){ %>checked <% } %>>
<label for="radio-3" class="radio-label">Female</label>
</div>
</div>
<div class="col-md-8">
<div class="form-group">
<label for="birthday" class="text-muted">Birthday</label>
<input type="text" name="birthday" value="<%=students.birthday%>" placeholder="MM/DD/YYYY">
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label for="program" class="text-muted">Program</label>
<input type="text" name="program" value="<%=students.program%>" placeholder="i.e. BSIT">
</div>
<div class="col-md-6">
<label for="yearLevel" class="text-muted">Year Level</label>
<select class="form-select" name="yearLevel">
<option value="">Select year level</option>
<option <% if(students.yearLevel == "First Year"){ %>selected <% } %> value="First Year">First Year</option>
<option <% if(students.yearLevel == "Second Year"){ %>selected <% } %> value="Second Year">Second Year</option>
<option <% if(students.yearLevel == "Third Year"){ %>selected <% } %> value="Third Year">Third Year</option>
<option <% if(students.yearLevel == "Fourth Year"){ %>selected <% } %> value="Fourth Year">Fourth Year</option>
<option <% if(students.yearLevel == "Fifth Year"){ %>selected <% } %> value="Fifth Year">Fifth Year</option>
<option <% if(students.yearLevel == "Masteral"){ %>selected <% } %> value="Masteral">Masteral</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<label for="email" class="text-muted">Email</label>
<input type="text" name="email" value="<%=students.email%>" placeholder="example#gmail.com">
</div>
<div class="form-group">
<label for="address" class="text-muted">Address</label>
<input type="text" name="address" value="<%=students.address%>" placeholder="Household No., Barangay, City, Province">
</div>
<div class="form-group">
<label for="contact" class="text-muted">Contact</label>
<input type="text" name="contact" value="<%=students.contact%>" placeholder="i.e 09XX-XXX-XXXX">
</div>
<div class="form-group">
<button type="submit" class="btn text-dark update">Save</button>
</div>
</div>
</form>
<!-- form handling -->
Code for my #update_student JS just in case:
$('#update_student').on("submit",(function(event){
event.preventDefault();
var unindexed_array = $(this).serializeArray();
var data = {}
$.map(unindexed_array,function(n,i){
data[n['firstName']] = n['value']
})
console.log(data);
var request={
"url": `http://localhost:1485/api/students/${data.id}`,
"method":"PUT",
"data" : data
}
$.ajax(request).done(function(response){
alert("Data updated successfully!");
})
}))
Thanks to Sir #Rajdeep Debnath 's help, I was able to look into may "unindexed_array" from my console.log and figured out that instead of data[n['firstName']] = n['value']
I should write data[n['name']] = n['value']
I wrote the former because I thought it is just the name of the variable but in actuality, it is like the "id" or "class" called in JavaScript. The form used "name" on the inputs (like <input type="text" name="program" value="<%=students.program%>" placeholder="i.e. BSIT"> from my code) so that's why it is the one called in the function instead.
Now my code for my #update_student JS goes like this:
$('#update_student').on("submit",(function(event){
event.preventDefault();
var unindexed_array = $(this).serializeArray();
var data = {}
$.map(unindexed_array,function(n,i){
data[n['name']] = n['value']
})
console.log(data);
var request={
"url": `http://localhost:1485/api/students/${data.id}`,
"method":"PUT",
"data" : data
}
$.ajax(request).done(function(response){
alert("Data updated successfully!");
})
}))
You just simply change your Url path with ``symbol instead of ''.
Just like that
var request={
"url": `http://localhost:1485/api/students/${data.id}`,
"method":"PUT",
"data" : data
}

Multiple Forms to same location in nodejs

I broke my form and am trying to make two different pages and finally PUT data to same initial route(ACTION), but I see data from the second page
only:
This is the first part of the form which I broke into the first page, keeping the action same:
<div class="container">
<div class="row">
<h1 style="text-align: center">Register Yourself</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/students" method="POST">
<label>Name:</label> <div class="form-group">
<input class="form-control" type="text" name="name" placeholder="name">
</div>
</form>
Proceed!
</div>
</div>
</div>
This is the second part of the form which I put in the second page:
<div class="container">
<div class="row">
<h1 style="text-align: center">Register Yourself</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/students" method="POST">
<label for="preference">Choose a catagory:</label>
<select name="preference" class="form-control">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Any">Any</option>
</select>
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary ">Submit!</button>
</div>
</form>
</div>
</div>
</div>
This is the route where we are taking data from form and adding to the db and posting finally:
router.post("/students",middleware.isLoggedIn, function(req, res){
// get data from form and add to students array
var name = req.body.name;
var preference = req.body.preference;
var author = {
id: req.user._id,
username: req.user.username
}
var newstudent = {name: name,preference: preference}
// Create a new student and save to DB
Student.create(newstudent, function(err, newlyCreated){
if(err){
console.log(err);
} else {
//redirect back to students page
console.log(newlyCreated);
res.redirect("/students");
}
});
});
I think you can follow this approach, however, if you have really big form. I advise you to create Modals for every step. Also, recommend you to create separate controller for forms. This is how you can achieve for the above form:
// I am assuming that you will show first form and then second form as there is no validation added
var formData = {name: name,preference: preference}; // when you have big forms create model for it
//step will make your route dynamic
router.post("/students/:step",middleware.isLoggedIn, function(req, res){
// get data from form and add to students array
if (req.params.step == 1) {
formData.name = req.body.name;
return '' //do nothing as you should submit form in next step
}
else {
formData.preference = req.body.preference;
Student.create(formData, function(err, newlyCreated){
if(err){
console.log(err);
} else {
//redirect back to students page
console.log(newlyCreated);
// res.redirect("/students"); // you don't need to redirect
formData = {name:'' ,preference: ''};
res.status(201).send({message: 'New User Created'});
}
});
}
});
In your HTML code:
<div class="container">
<div class="row">
<h1 style="text-align: center">Register Yourself</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/students/1" method="POST"> //add id for every step
<label for="preference">Choose a catagory:</label>
<select name="preference" class="form-control">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Any">Any</option>
</select>
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary ">Submit!</button>
</div>
</form>
</div>
</div>
</div>
<div class="container">
<div class="row">
<h1 style="text-align: center">Register Yourself</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/students/2" method="POST"> //add id for every step
<label for="preference">Choose a catagory:</label>
<select name="preference" class="form-control">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Any">Any</option>
</select>
</div>
<div class="form-group">
<button class="btn btn-sm btn-primary ">Submit!</button>
</div>
</form>
</div>
</div>
</div>
At this moment, I can think of this approach.

How to retrieve older form data before updating it to new one using NodeJS, Express and mongodb! Ejs is the template?

I need to retrieve all older data of a form, before updating it to new one. I need those form data for a reporting purpose. It basically will be the version of a data.
I am working on #Nodejs #ExpressJS #EJS as template and #MONGODB,#mongoose.
Below are the images of the code! I am new to the programming so please help me with the coding part not describe it using coding Jargans!
Schema Snippet
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define the schema for our user model
var procedureschema = mongoose.Schema({
proceduretype : String,
procedurename : String,
procedurenumber : String,
scope : String,
status:{type:String,lowercase:true,enum:["draft", "active", "pending"]},
forms : String,
relatedprocedure : String,
norms : String,
qualityrecords : String,
expdate : String,
companyname : String,
version : String,
owner: String,
approver : String,
procedurefiles : String,
flowchart : String,
proceduredescription : String,
isotags : String,
departmentname : String
});
// generating a password hash
// create the model for users and expose it to our app
module.exports = mongoose.model('Procedure', procedureschema);
Form view EJS page
<% include sidebar.ejs %>
<div class="dt-content">
<!-- Page Header -->
<!-- <div class="dt-page__header">
<h1 class="dt-page__title">New Procedure</h1>
</div> -->
<!-- /page header -->
<!-- Grid -->
<div class="row">
<!-- Grid Item -->
<div class="col-xl-12">
<!-- Card -->
<div class="dt-card">
<div class="dt-card__header">
<!-- Card Heading -->
<div class="dt-card__heading">
<h3 class="dt-card__title">New Procedure</h3>
</div>
<!-- /card heading -->
<a type="button" href="/admin/add/procedure/forms" role="button" class="btn btn-dark mr-2 mb-2"> Add Forms</a>
<a type="button" href="/admin/add/procedure/type" role="button" class="btn btn-dark mr-2 mb-2"> Add Procedure Type</a>
<a type="button" href="/admin/add/procedure/norms" role="button" class="btn btn-dark mr-2 mb-2"> Add Norms</a>
<a type="button" href="/admin/add/procedure/tags" role="button" class="btn btn-dark mr-2 mb-2"> Add Procedure Tags</a>
</div>
<!-- Card Header -->
<!-- /card header -->
<div class="dt-card__body">
<form action="/admin/create/procedure" method="post" enctype="multipart/form-data">
<div class="form-row">
<div class="col-sm-6 mb-3">
<label>Procedure Type</label>
<div class="input-group">
<select class="custom-select" name="proceduretype" id="inputGroupSelect04">
<option selected>Choose Procedure Type</option>
<% procedurecat.forEach(function(data){%>
<option value="<%=data.category_name %>"><%=data.category_name %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Procedure Name</label>
<input type="text" class="form-control" id="validationDefault03" name="procedurename" placeholder="Enter Procedure Name"
required>
</div>
<div class="col-sm-6 mb-3">
<label>Procedure Number</label>
<input type="number" class="form-control" name="procedurenumber" id="validationDefault03" placeholder="Enter Procedure Number"
required>
</div>
<div class="col-sm-6 mb-3">
<label>Scope</label>
<input type="text" class="form-control" id="validationDefault03" name="scope" placeholder="Enater Procedure Scope"
required>
</div>
<div class="col-sm-6 mb-3">
<label>Status</label>
<div class="input-group">
<select class="custom-select" name="status" id="inputGroupSelect04">
<option selected>Choose Status</option>
<option value="draft">Draft</option>
<option value="pending">Pending</option>
<option value="active">Active</option>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Forms</label>
<div class="input-group">
<select class="custom-select" name="forms" id="inputGroupSelect04">
<option selected>Choose Forms</option>
<% forms.forEach(function(data){%>
<option value="<%=data.forms_name %>"><%=data.forms_name %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Related Procedure</label>
<div class="input-group">
<select class="custom-select" name="relatedprocedure" id="inputGroupSelect04">
<option selected>Choose Related Procedures</option>
<% proceduretitle.forEach(function(data){%>
<option value="<%=data.procedurename %>"><%=data.procedurename %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Select Norms</label>
<div class="input-group">
<select class="custom-select" name="norms" id="inputGroupSelect04">
<option selected>Choose Norms</option>
<% norms.forEach(function(data){%>
<option value="<%=data.norms_name %>"><%=data.norms_name %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Quality Records</label>
<input type="text" name="qualityrecords" class="form-control" id="validationDefault03"
placeholder="Enter Quality Records Here" required>
</div>
<div class="col-sm-6 mb-3">
<label>Expiration Date</label>
<div class="input-group date" id="date-time-picker-1" data-target-input="nearest">
<input type="text" name = "expdate" class="form-control datetimepicker-input" data-target="#date-time-picker-1" />
<div class="input-group-append" data-target="#date-time-picker-1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="icon icon-calendar"></i></div>
</div>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Company Name</label>
<input type="text" value="<%= user.companyname %>" name="companyname" class="form-control" id="validationDefault03" readonly
>
</div>
<div class="col-sm-6 mb-3">
<label>Version</label>
<input type="number" step ="0.1" name="version" class="form-control" id="validationDefault03" placeholder="Auto Increased field"
required>
</div>
<div class="col-sm-6 mb-3">
<label>Owner</label>
<div class="input-group">
<select class="custom-select" name="owner" id="inputGroupSelect04">
<option selected>Choose Owner</option>
<% users.forEach(function(data){%>
<option value="<%=data.name %>"><%=data.name %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Approver</label>
<div class="input-group">
<select class="custom-select" name="approver" id="inputGroupSelect04">
<option selected>Choose Approver</option>
<% users.forEach(function(data){%>
<option value="<%=data.name %>"><%=data.name %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-6 mb-3">
<label>Departmnent Name</label>
<div class="input-group">
<select class="custom-select" name="departmentname" id="inputGroupSelect04">
<option selected>Choose Department Name</option>
<% department.forEach(function(data){%>
<option value="<%=data.departmentname %>"><%=data.departmentname %></option>
<%})%>
</select>
</div>
</div>
<div class="col-sm-12 mb-3 form-row">
<label class=" col-form-label text-sm-left" for="file-field">Attached Files</label>
<div class="col-md-12 col-sm-9">
<div class="custom-file">
<input type="file" name="procedurefiles" onchange="GetFileSizeNameAndType()" id="file" class="custom-file-input" id="file-field" multiple>
<label class="custom-file-label" for="file-field">Attacthed your files here ..</label>
</div>
</div>
<div class="form-row input-group">
<div class="col-md-6 col-sm-6 form-row">
<div id="fp"></div>
</div>
</div>
</div>
<div class=" col-sm-12 mb-4 ">
<label class=" text-sm-left mb-4">Flowchart</label>
<button type="button" href="javascript:void(0)" role="button" class="btn btn-dark mr-2 mb-2">Design your flowchart</button>
</div>
<div class=" col-sm-12 mb-4 ">
<label>Description</label>
<textarea class=" col-sm-12 mb-4" name="proceduredescription" id="summernote"></textarea>
</div>
</div>
<hr class="border-dashed my-8">
<div class=" form-row mb-4 ">
<label class="col-md-2 col-sm-3 text-sm-right mb-4 mb-sm-0">Read Confirmation</label>
<div class="col-md-10 col-sm-9">
<!-- Checkbox -->
<div class="custom-control custom-checkbox custom-control-inline">
<input type="checkbox" id="customcheckboxInline1" name="customcheckboxInline1"
class="custom-control-input" checked>
<label class="custom-control-label" for="customcheckboxInline1"></label>
</div>
</div>
</div>
<hr class="border-dashed my-8">
<div class="form-group form-row mb-0 col-md-12">
<button type="submit" class="btn btn-primary text-uppercase">Submit this procedure</button>
</div>
</form>
</div>
<!-- Card Body -->
</div>
<!-- /card body -->
</div>
<!-- /card -->
</div>
<!-- /grid item -->
</div>
<!-- /grid -->
<!-- /site content -->
<% include footer.ejs %>
<script>
$(document).ready(function() {
$('#summernote').summernote();
});</script>
<script>
function GetFileSizeNameAndType()
{
var fi = document.getElementById('file'); // GET THE FILE INPUT AS VARIABLE.
var totalFileSize = 0;
// VALIDATE OR CHECK IF ANY FILE IS SELECTED.
if (fi.files.length > 0)
{
// RUN A LOOP TO CHECK EACH SELECTED FILE.
for (var i = 0; i <= fi.files.length - 1; i++)
{
//ACCESS THE SIZE PROPERTY OF THE ITEM OBJECT IN FILES COLLECTION. IN THIS WAY ALSO GET OTHER PROPERTIES LIKE FILENAME AND FILETYPE
var fsize = fi.files.item(i).size;
totalFileSize = totalFileSize + fsize;
document.getElementById('fp').innerHTML = document.getElementById('fp').innerHTML + '<br /> ' + 'File Name is <b>' + fi.files.item(i).name + "</b>.";
}
}
document.getElementById('divTotalSize').innerHTML = "Total File(s) Size is <b>" + Math.round(totalFileSize / 1024) + "</b> KB";
}
</script>
Routes of that form Post and Update API
app.post('/create/procedure', function (req, res) {
let proceduresinglefiles = req.files.procedurefiles
if(Array.isArray(proceduresinglefiles)==false){
console.log(Array.isArray(proceduresinglefiles));
console.log(typeof(proceduresinglefiles));
console.log(proceduresinglefiles);
var filename = proceduresinglefiles.name;
proceduresinglefiles.mv('./public/assets/documents/procedure/' + filename, function(err) {
if (err)
console.log(err);
});
var procedure = Procedure();
procedure.proceduretype = req.body.proceduretype;
procedure.procedurename = req.body.procedurename;
procedure.procedurenumber = req.body.procedurenumber;
procedure.scope = req.body.scope;
procedure.status = req.body.status;
procedure.forms = req.body.forms;
procedure.relatedprocedure = req.body.relatedprocedure;
procedure.norms = req.body.norms;
procedure.qualityrecords = req.body.qualityrecords;
procedure.expdate = req.body.expdate;
procedure.companyname = req.body.companyname;
procedure.version = req.body.version;
procedure.owner = req.body.owner;
procedure.approver = req.body.approver;
procedure.procedurefiles = filename;
procedure.flowchart = req.body.flowchart;
procedure.proceduredescription = req.body.proceduredescription;
procedure.isotags = req.body.isotags;
procedure.departmentname = req.body.departmentname
procedure.save(function (err, getprocedure) {
if (err) res.json(err);
else {
console.log(getprocedure);
res.redirect("/admin/view/procedure");
}
})
}
else
{
var filenamea=[];
for(var i=0;i<proceduresinglefiles.length;i++){
console.log(proceduresinglefiles.length);
console.log(i);
var procedurefilename = proceduresinglefiles[i].name;
console.log(procedurefilename);
filenamea[i]=procedurefilename;
console.log(filenamea);
proceduresinglefiles[i].mv('./public/assets/documents/procedure/' + procedurefilename, function(err) {
if (err)
console.log(err);
});
}
let multipleprocedurefilename= filenamea.toString();
var procedure = Procedure();
procedure.proceduretype = req.body.proceduretype;
procedure.procedurename = req.body.procedurename;
procedure.procedurenumber = req.body.procedurenumber;
procedure.scope = req.body.scope;
procedure.status = req.body.status;
procedure.forms = req.body.forms;
procedure.relatedprocedure = req.body.relatedprocedure;
procedure.norms = req.body.norms;
procedure.qualityrecords = req.body.qualityrecords;
procedure.expdate = req.body.expdate;
procedure.companyname = req.body.companyname;
procedure.version = req.body.version;
procedure.owner = req.body.owner;
procedure.approver = req.body.approver;
procedure.procedurefiles = multipleprocedurefilename;
procedure.flowchart = req.body.flowchart;
procedure.proceduredescription = req.body.proceduredescription;
procedure.isotags = req.body.isotags;
procedure.departmentname = req.body.departmentname
procedure.save(function (err, getprocedure) {
if (err) res.json(err);
else {
console.log(getprocedure);
res.redirect("/admin/view/procedure");
}
})
}
});
app.post('/edit/procedure/:id',(req, res) => {
Procedure.findOneAndUpdate({_id:req.params.id},{
$set:{
proceduretype : req.body.proceduretype,
procedurename : req.body.procedurename,
procedurenumber : req.body.procedurenumber,
scope : req.body.scope,
status : req.body.status,
forms : req.body.forms,
relatedprocedure : req.body.relatedprocedure,
norms : req.body.norms,
qualityrecords : req.body.qualityrecords,
expdate : req.body.expdate,
companyname : req.body.companyname,
version : req.body.version,
owner : req.body.owner,
approver : req.body.approver,
procedurefiles : req.body.procedurefiles,
flowchart : req.body.flowchart,
proceduredescription : req.body.proceduredescription,
isotags : req.body.isotags,
departmentname : req.body.departmentname
}},
{new: true, upsert:true},
function(err, procedurenew){
if(err){
console.log(err);
}
else
{
console.log(procedurenew);
res.redirect('/admin/view/procedure')
}
}
)
});
As far as I understand your problem, you need the old data before updating it to new one?
So you need to change(new:false) in your query API and your API code looks like:
app.post('/edit/procedure/:id',(req, res) => {
Procedure.findOneAndUpdate({_id:req.params.id},{
$set:{
proceduretype : req.body.proceduretype,
procedurename : req.body.procedurename,
procedurenumber : req.body.procedurenumber,
scope : req.body.scope,
status : req.body.status,
forms : req.body.forms,
relatedprocedure : req.body.relatedprocedure,
norms : req.body.norms,
qualityrecords : req.body.qualityrecords,
expdate : req.body.expdate,
companyname : req.body.companyname,
version : req.body.version,
owner : req.body.owner,
approver : req.body.approver,
procedurefiles : req.body.procedurefiles,
flowchart : req.body.flowchart,
proceduredescription : req.body.proceduredescription,
isotags : req.body.isotags,
departmentname : req.body.departmentname
}},
{new: false, upsert:true},
function(err, procedurenew){
if(err){
console.log(err);
}
else
{
console.log(procedurenew);
res.redirect('/admin/view/procedure')
}
}
)
});
[DO VOTE TO THIS ANSWER, IF ITS HELPFUL TO YOU]

SailsJS : Mysterious null values

my problem is that whenever a new client is created, all the values are null in the database except the id, the name, responsable and the logo. i dont think i did a programmation mistake, so i think it is a case of callbacks race but i cant found the solution.
P.S : the problem occure only if i select and send an image file to be uploaded, in the other case, the client values are stored correctly.
P.S 2 : the problem occure in my remote server only, in local environnement all is ok !
Than you very much !
UPDATE : i included the code for my create.ejs view
This is the code of the store method in my ClientService :
store: function(req, done) {
var name = req.param('name'),
town = req.param('town'),
adress = req.param('adress'),
postalCode = req.param('postalCode'),
telephone = req.param('telephone'),
email = req.param('email'),
fax = req.param('fax'),
responsable = req.param('responsable'),
website = req.param('website'),
activity = req.param('activity');
comments = req.param('comments');
Client.create({
name: name,
town: town,
adress: adress,
postalCode: postalCode,
telephone: telephone,
fax: fax,
responsable: responsable,
website: website,
activity: activity,
email: email,
comments: comments
}).exec(function(err, client) {
if (err) console.log(err);
req.file('logo').upload(
{
dirname: sails.config.appPath + sails.config.params.logos
},
function(err, logo) {
if (err) return done(err, null);
if (logo.length !== 0) {
client.logo = require('path').basename(logo[0].fd);
} else {
client.logo = 'default.png';
}
client.save(function(err) {
return done(null, client);
});
}
);
});
}
And this is the code for the EJS view :
<div class="portlet-body form">
<!-- BEGIN FORM-->
<form action="store" method="POST" class="form-horizontal" enctype="multipart/form-data">
<div class="form-body">
<div class="row">
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="name">
<label for="form_control_1">Nom du Client</label>
<i class="fa fa-institution"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="activity">
<label for="form_control_1">Activité</label>
<i class="icon-star"></i>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="responsable">
<label for="form_control_1">Responsable</label>
<i class="icon-user"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group" style="margin-left:15px;">
<div class="form-photo-label-form" >
<i class="icon-picture icon-create"></i>
<label for="form_control_1" class="form-photo-create" >Photo </label>
</div>
<br>
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn green btn-file">
<span class="fileinput-new"> Selectionner Fichier </span>
<span class="fileinput-exists"> Changer </span>
<input type="file" name="logo"> </span>
<span class="fileinput-filename"> </span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="email">
<label for="form_control_1">Email</label>
<i class="fa fa-inbox"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="adress">
<label for="form_control_1">Adresse</label>
<i class="icon-home"></i>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="postalCode">
<label for="form_control_1">Code postale</label>
<i class="fa fa-send"></i>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="town">
<label for="form_control_1">Ville</label>
<i class=" fa fa-map"></i>
</div>
</div>
</div>
<!--/span-->
</div>
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-12">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<textarea class="form-control" rows="3" style="height: 192px; resize:none " name="comments"></textarea>
<label for="form_control_1">Commentaire</label>
<i class=" fa fa-edit"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-12">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="telephone">
<label for="form_control_1">Telephone</label>
<i class="icon-screen-smartphone"></i>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="fax">
<label for="form_control_1">Fax</label>
<i class="fa fa-fax"></i>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group form-md-line-input has-success form-md-floating-label form-create">
<div class="input-icon">
<input type="text" class="form-control" name="website">
<label for="form_control_1">Site Internet</label>
<i class=" fa fa-internet-explorer"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-actions right">
<button type="button" class="btn default">Annuler</button>
<button type="submit" class="btn green"><i class="fa fa-check"></i> Enregistrer</button>
</div>
</form>
Nothing mysterious (:
Your problem is that You use req.param instead of req.body
And Your code is simply should look like this:
const path = require('path'); // somewhere in same module at the top
store: (req, done) => {
Client
.create(req.body)
.exec((err, client) => {
if(err) {
// no need to go further
// if You cannot create database record
return done(err);
}
const dirname = path.join(sails.config.appPath, sails.config.params.logos); // safely concatenates paths based on OS
req
.file('logo')
.upload({dirname}, (err, logo) => {
if (err) {
// we created record (client)
// but could not save the file
// it should not be a stopper
console.error(err);
}
client.logo = (logo) ? path.basename(logo[0].fd) : 'default.png';
client.save((err) => {
if(err) {
// just log the error and continue
console.error(err);
}
done(null, client);
});
});
});
}
P.S. When You pass req.body (or any other) object to Client.create don't worry about object contents, just define field constrains in You model file, ODM (or ORM) will just handle validation automatically based on constraints and will prevent from creating null valued fields
Example:
module.exports = {
attributes: {
name: {
// it requires field name:
// to be defined (required: true),
// to be string (type),
// to have at least 2 symbols,
// to not exceed 100 symbols
type: 'string',
required: true,
minLength: 2,
maxLength: 100
},
email: {
// it requires field email:
// to be defined (required: true),
// to be email (type),
// to be unique among documents, records, rows
type: 'email',
required: true,
unique: true
},
... and so on ...
}
}
More about validation here
Thanks everybody. I solved the problem by putting the file input at the end the form. Like you suggested, the values after the file input were reset after the upload of the file

How to update a record using Sequelize?

I am trying to update the records form a table by using Sequelize.
Unfortunately, the id of the event I am trying to update seems to be undefined. How can I send it correctly?
The block of code I have in my controller looks like this:
router.get('/edit/:eventid', function(req, res) {
var eventid = req.params.eventid;
Event.findById(req.params.eventid).then(function(event) {
eventid= event.eventid;
title= event.title;
description= event.description;
availabletickets=event.availabletickets;
date= event.date;
newDate= date.toString();
newdate= newDate.substring(0,21);
console.log(eventid);
}) .then(function() {
res.render('eventEdit', {
eventid: eventid,
pagetitle: ' Edit Event',
title: title,
description:description,
availabletickets:availabletickets,
newdate: newdate,
});
})
.catch(function(error) {
res.render('error', {
error: error
});
});
});
router.post('/edit', function(req, res){
var eventid = req.body.eventid;
var title = req.body.title;
var description = req.body.description;
var availabletickets= req.body.availabletickets;
var date = req.body.date;
console.log( eventid); //this returns undefined.
console.log('title, description, availabletickets, date);
const newData = {
title: title,
date: date,
description: description,
availabletickets: availabletickets
};
Event.update(
newData,
{
where:{
eventid:eventid
}
}
).then(function() {
console.log("Event updated");
res.redirect('/events');
}).catch(e => console.error(e));
});
Although, the HTML file,where the user introduces the values when editing the events, looks like this:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment"><%= description %></textarea> <br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>"> <br>
<label> Data:<%= newdate %> </label> <br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;" ><br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>
You get the eventid as undefined because req.body doesn't contain the eventid (it's not passed from the client side). To pass it from the client side you have to add an input having the name="eventid" attribute.
In the EJS template you need to render the eventid value as a hidden input (<input type="hidden" ...)
You can do that by added in your form this line:
<input type="hidden" value="<%= eventid %>" name="eventid" />
This is the updated form code:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<input type="hidden" value="<%= eventid %>" name="eventid" />
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment">
<%= description %>
</textarea>
<br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>">
<br>
<label> Data:
<%= newdate %>
</label>
<br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;">
<br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>

Resources