I push an object to my Array in mongoose, array only stores its length - arrays

I try to push an object into an Array in mongoose, but whenever i do it, it puts its length like this(mongoose, the attribute is schoolComment at the bottom), I am using mlab.com for database.
{
"_id": {
"$oid": "58e17ee3e24dfb1f70d76460"
},
"schoolName": "Koc Universitesi",
"schoolIlce": "Sariyer",
"schoolSehir": "Istanbul",
"schoolId": 981299,
"__v": 5,
"schoolComments": [
3
]
}
this is my code in node JS (The comments are not appearing in html because of this reason)
app.post('/comment', function(req, res){
if(req.session.user && req.session){
User.findOne({email: req.session.user.email}, function(err, user){
if(err) {
res.send('error');
}
if(user){
if(req.session.user.password === user.password){
var thisID = user.userid;
Universite.findOne({schoolName: req.body.collegeName}, function(err, college){
if(err) res.send('error');
if(college){
college.set({schoolComments: college.schoolComments.push({thisID: req.body.comment})}).save(function(err){
if(err){
res.render('errors', {error:'Error'});
}else{
res.locals.college = college;
res.locals.user = user;
res.render('universiteinfoUser');
}
});
}
});
}else{
res.render('login', {});
}
}
});
}
});
and this is HTML DOM Form for it. The comments are not appearing because of this reasons.
<form onkeypress="enterPress();" action="/comment" method="post">
<textarea maxlength="100" style="font-size: 25px;" name="comment" rows="3" cols="50" placeholder="Yorumunuzu yazin..."></textarea><br>
<input style="display: none; visibility: hidden;" type="text" name="collegeName" value="<%=college.schoolName%>"></input>
<button type="submit" name="commentSubmit">Comment Submit</button>
</form>
<div class="userCommentDisplay">
<ul>
<%college.schoolComments.forEach(function(item, i){%>
<%var k = college.schoolComments[i]%>
<%for(key in k){%>
<%if(key === user.userid){%>
<li><%=k[key]%> Same</li>
<%}else{%>
<li><%=k[key]%></li>
<%}%>
<%}%>
<%})%>
</ul>
</div>

You may want to use findOneAndUpdate and build your comment item dynamically (to set the dynamic field name) :
var item = {};
item[user.userid] = req.body.comment;
Universite.findOneAndUpdate({
schoolName: req.body.collegeName
}, {
$push: {
"schoolComments": item
}
}, { new: true }, function(err, college) {
if (err) {
res.render('errors', { error: 'Error' });
} else {
res.locals.college = college;
res.locals.user = user;
res.render('universiteinfoUser');
}
});
Note that I've aded { new: true } in order to return the modified document college instead of the unaltered one.
FYI, in your code, you have used JS method Array.prototype.push() that will return the new length of the array by using college.schoolComments.push

Related

How to pass JSON Array {{this.row}} to submit() function to get posted using Axios.post

this.row is Generating form input into JSON Array which I'm trying to post via submit function using Axios but unable to the value please help what's wrong ??
Axios postcode
axios.post('/submit', this.rows).then(response => {
this.rows; //Clear input fields.
this.loaded = true;
Here is my complete code
<template>
<form #submit.prevent="submit">
{{ /* These are 3 buttons which are calling 3 different function to create input boxes */ }}
<div class="d-flex mt-5"><div>
<label>Add A</label>
<button type="button" #click="addRow">01</button>
</div>
<div> <label>Add B</label>
<button type="button" #click="addRow1">02</button>
</div>
<div> <label>Add c</label>
<button type="button" #click="addRow3">03</button>
</div>
</div>
{{ /* this section calls button-counter template from script code */ }}
<div v-for="row in rows" :key="row.id">
<button-counter :name ="row.name" :id="row.id" :value.sync="row.value"></button-counter>
</div>
<div>
<button type="submit" class="btn btn-primary">Add Points</button>
</div>
<div v-if="success" class="alert alert-success mt-3">
Message sent!
</div>
</form>
</template>
<script>
Vue.component("button-counter", {
props: {
value: {
default: "",
}
},
/* This is my template which gets called fro the addition of new inputs ...guess here I need to add v-model so that dynamically generated fields will be posted but I'm unable to get it posted */
template: '<input class="form-control" id= id.row name=row.name type="number" style="margin-top: 10px;" :value="value" #change="$emit(\'update:value\', $event.target.value)">'
});
export default {
props: ['gameId','userId'],
mounted() {
console.log('Component mounted.')
},
data() {
return {
gamex: this.gameId,
rows: [],
count: 0,
fields: {},
errors: {},
success: false,
loaded: true,
};
},
computed: {
total() {
if (this.rows.length) {
return this.rows.reduce((acc, row) => acc += parseInt(row.value), 0);
}
return 0;
}
},
methods: {
addRow: function() {
var txtCount = 1;
let id = "txt_" + txtCount;
this.rows.push({ name:'zero',value:100, description: "textbox1", id });
},
addRow1: function() {
var txtCount = 1;
let id = "txt2_" + txtCount;
this.rows.push({name:'one',value:200, description: "textbox2", id });
},
addRow3: function() {
var txtCount = 1;
let id = "txt3_" + txtCount;
this.rows.push({name:'two',value:300, description: "textbox3", id });
},
submit: function() {
if (this.loaded) {
this.loaded = false;
this.success = false;
this.errors = {};
axios.post('/submit', this.rows).then(response => {
this.rows; //Clear input fields.
this.loaded = true;
this.success = true;
}).catch(error => {
this.loaded = true;
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
});
}
},
followUser() {
axios.post('/chklet/' + this.userId)
.then(response => {
return response.data ;
});
}
},
mounted () {
this.followUser();
}
};
</script>
You can use JSON.stringify(array_to_convert_in_string_to_send_in_ajax) but you will have to json_decode it also in backend server
In server section for example laravel:
$result = json_decode($request->your_array);

How can I make square-connect work with angularjs?

Basing myself on the example provided by the SquareUp documentation (https://github.com/square/connect-api-examples.git). I am trying to integrate squareup to process payments with CC but I do not know what happens.
the view:
<div class="bg-light lter b-b wrapper-md">
<h1 class="m-n font-thin h3"></h1>
</div>
<div class="wrapper-md" >
<div class="row">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading font-bold">CC info</div>
<div class="panel-body">
<div class="no-boot" ng-controller="PaymentController" ng-cloak>
<div id="successNotification" ng-show="isPaymentSuccess">
Card Charged Succesfully!!
</div>
<form novalidate id="payment-form" ng-hide="isPaymentSuccess">
<div id="card-errors" ng-repeat="error in card_errors">
<li>{{error.message}}</li>
</div>
<div>
<label>Card Number</label>
<div ng-model="data.card.card_number" id="sq-card-number"></div>
</div>
<div>
<label>CVV</label>
<div ng-model="data.card.cvv" id="sq-cvv"></div>
</div>
<div>
<label>Expiration Date</label>
<div ng-model="data.card.expiration_date" id="sq-expiration-date"></div>
</div>
<div>
<label>Postal Code</label>
<div ng-model="data.card.postal_code" id="sq-postal-code"></div>
</div>
<div>
<input ng-click="submitForm()" ng-disabled="isProcessing" type="submit" id="submit" value="Buy Now" class="btn btn-primary">
</div>
</form>
<button id="sq-apple-pay" class="button-apple-pay-block" ng-show="supportApplePay"></button>
</div>
</div>
</div>
</div>
</div>
</div>
the controller:
'use strict';
/* Controllers */
// signin controller
app.controller('PaymentController', ['$scope', '$http', function($scope, $http) {
//for showing #successNotification div
$scope.isPaymentSuccess = false;
//for disabling payment button
$scope.isProcessing = false;
//for disabling apple pay button
$scope.supportApplePay = false;
$scope.data = {
product_id: "001",
user: {},
card: {},
products: {
"001": {
"name": "Paper Origami 1:10,000 scale model (11 inch)",
"value":"1.0",
},
"002": {
"name": "Plastic 1:5000 scale model (22 inch)",
"value":"49.0",
},
"003": {
"name": "Metal & Concrete 1:1000 scale replica (9 feet)",
"value":"5000.0",
}
}
};
$scope.submitForm = function(){
console.log($scope.data)
$scope.isProcessing = true;
$scope.paymentForm.requestCardNonce();
return false
}
var cardNumber = $scope.data.card.card_number = 5409889944179029;
var cvv = $scope.data.card.cvv = 111;
var expirationDate = $scope.data.card.expirationDate = '02/21';
var postalCode = $scope.data.card.postalCode = 3311;
$scope.paymentForm = new SqPaymentForm({
applicationId: 'sandbox-sq0idp-IsHp4BXhhVus21G5JPyYpw',
locationId: 'CBASECJCvmqtoIL1fn3iReEjQRcgAQ',
inputClass: 'sq-input',
inputStyles: [
{
fontSize: '14px',
padding: '7px 12px',
backgroundColor: "transparent"
}
],
cardNumber: {
elementId: 'sq-card-number',
placeholder: '5409889944179029',
value: '5409889944179029'
},
cvv: {
elementId: 'sq-cvv',
placeholder: '111',
value: '111'
},
expirationDate: {
elementId: 'sq-expiration-date',
placeholder: '04/21',
value: '04/21'
},
postalCode: {
elementId: 'sq-postal-code',
placeholder: '33114',
value: '33114'
},
applePay: {
elementId: 'sq-apple-pay'
},
// cardNumber:''+cardNumber,
// cvv:''+cvv,
// expirationDate:''+expirationDate,
// postalCode:''+postalCode,
callbacks: {
cardNonceResponseReceived: function(errors, nonce, cardData) {
if (errors){
$scope.card_errors = errors
$scope.isProcessing = false;
$scope.$apply(); // required since this is not an angular function
}else{
$scope.card_errors = []
$scope.chargeCardWithNonce(nonce);
}
},
unsupportedBrowserDetected: function() {
// Alert the buyer
},
methodsSupported: function (methods) {
console.log(methods);
$scope.supportApplePay = true
$scope.$apply(); // required since this is not an angular function
},
createPaymentRequest: function () {
var product = $scope.data.products[$scope.data.product_id];
return {
requestShippingAddress: true,
currencyCode: "USD",
countryCode: "US",
total: {
label: product["name"],
amount: product["value"],
pending: false,
}
};
},
// Fill in these cases to respond to various events that can occur while a
// buyer is using the payment form.
inputEventReceived: function(inputEvent) {
switch (inputEvent.eventType) {
case 'focusClassAdded':
// Handle as desired
break;
case 'focusClassRemoved':
// Handle as desired
break;
case 'errorClassAdded':
// Handle as desired
break;
case 'errorClassRemoved':
// Handle as desired
break;
case 'cardBrandChanged':
// Handle as desired
break;
case 'postalCodeChanged':
// Handle as desired
break;
}
}
}
});
$scope.chargeCardWithNonce = function(nonce) {
alert("no");
var url = "libs/php_payment/process-card.php";
var data = {
nonce: nonce,
product_id: $scope.data.product_id,
name: $scope.data.user.name,
email: $scope.data.user.email,
street_address_1: $scope.data.user.street_address_1,
street_address_2: $scope.data.user.street_address_2,
city: $scope.data.user.city,
state: $scope.data.user.state,
zip: $scope.data.user.zip
};
$http.post(url, data).success(function(data, status) {
if (data.status == 400){
// display server side card processing errors
$scope.isPaymentSuccess = false;
$scope.card_errors = []
for (var i =0; i < data.errors.length; i++){
$scope.card_errors.push({message: data.errors[i].detail})
}
}else if (data.status == 200) {
$scope.isPaymentSuccess = true;
}
$scope.isProcessing = false;
}).error(function(){
$scope.isPaymentSuccess = false;
$scope.isProcessing = false;
$scope.card_errors = [{message: "Processing error, please try again!"}];
})
}
//build payment form after controller loads
var init = function () {
$scope.paymentForm.build()
};
init();
}]);
error: "Error: [$rootScope:inprog] $digest already in progress
I haven't done angular in a while, but I'm betting that your issue is in:
methodsSupported: function (methods) {
console.log(methods);
$scope.supportApplePay = true
$scope.$apply(); // required since this is not an angular function
},
You are calling $apply() after a non-asyc call, generally you apply new data that you got asynchronously. See Angular Docs

VueJs2:remove item from parent array in component

I have a component with prop List. List is list of input files. At once input changed I add another one input.
Weird behavior if I try to delete .
https://jsfiddle.net/apokjqxx/115/
removeAnother: function(item) {
var vm = this;
var num = vm.$parent.cornerList.indexOf(item);
vm.$parent.cornerList.splice(num, 1);
},
How to reproduce:
choose file in first input
choose file in second input (will added after step 1)
choose file in third input (will added after step 2)
then click to remove on first item in list
Expected: removed first item but has removed last added
Use a key on your list.
<div v-for="(item, index) in list" :key="item.id">
I modified your fiddle to generate an id for each object added to the cornerList array.
var formuploadimage = Vue.extend({
template: '#template-form-upload-image',
props: {
list: {
type: Array
}
},
data: function() {
return {
isFileChanged: false
}
},
watch: {
validCnt: function() {
},
},
methods: {
onFileChange: function(item) {
var vm = this;
let id = Math.max.apply(Math, vm.$parent.cornerList.map(c => c.id)) + 1
var newItem = {id};
vm.$parent.cornerList.push(newItem);
},
removeAnother: function(item) {
var vm = this;
var num = vm.$parent.cornerList.indexOf(item);
vm.$parent.cornerList.splice(num, 1);
},
},
});
var app = new Vue({
el: ".lists-wrappers",
data: {
cornerList: [{id: 1}],
},
components: {
formuploadimage: formuploadimage
},
methods: {
},
});
.select-file{
width:250px;
border:1px solid red;
}
<script src="https://unpkg.com/vue#2.4.4/dist/vue.js"></script>
<div class="lists-wrappers">
<formuploadimage :list="cornerList"></formuploadimage>
</div>
<script type="text/x-template" id="template-form-upload-image">
<div>
<div v-for="(item, index) in list" :key="item.id">
<div class="select-file">
REMOVE<br/>
<label for="file-input">
+Add photo
</label>
<input type="file" #change="onFileChange(item)" />
</div>
</div>
</div>
</script>

post with angular gives error: possibly unhandled rejection

I've just managed to get my $http post working over Angular.where the admin only can make edit for data such gives permission to user to be admin or block user and update the user's description. I write every thing I learnt, but it gives me the below error when I post the data it gives this error in my Command prompt :
errors:
{ password:
{ MongooseError: Password should contain #$#! upper and lower case and should be between 6 and 8 characters
at ValidatorError (C:\jobapp\node_modules\mongoose\lib\error\validator.js:24:11)
at validate (C:\jobapp\node_modules\mongoose\lib\schematype.js:732:13)
at C:\jobapp\node_modules\mongoose\lib\schematype.js:802:5
at model.validator (C:\jobapp\node_modules\mongoose-validator\lib\mongoose-validator.js:55:16)
at asyncValidate (C:\jobapp\node_modules\mongoose\lib\schematype.js:791:29)
at deprecated (internal/util.js:41:15)
at C:\jobapp\node_modules\mongoose\lib\schematype.js:760:9
at Array.forEach (native)
at SchemaString.SchemaType.doValidate (C:\jobapp\node_modules\mongoose\lib\schematype.js:738:19)
at C:\jobapp\node_modules\mongoose\lib\document.js:1479:9
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
message: 'Password should contain #$#! upper and lower case and should be between 6 and 8 characters', name: 'ValidatorError',
properties: [Object],
kind: 'user defined',
path: 'password',
value: '$2a$10$cNJ6jAYs8bLZy5qE4RSMoeKbvz1PFZPRkK8T1ODxnD5QNRFxCrH5K',
reason: undefined } },
message: 'Users validation failed',
name: 'ValidationError' }
{ MongooseError: Users validation failed
at ValidationError }
When I refresh the page I got this error in console:
angular.js:14525 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"PUT","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/sign/edit/","data":{"_id":"590470c0d9f3c1187002431c","aboutme":"dsdjksjkdjk"},"headers":{"Accept":"application/json, text/plain, /","Content-Type":"application/json;charset=utf-8","x-access-token"
My code in my server call in Express.js to my MongoDB:
//insert new value
rout.put('/edit', function(req, res){
var editUser = req.body._id;
if(req.body.permission) var newPermission = req.body.permission;
if(req.body.block) var newBlock = req.body.block;
if(req.body.aboutme) var newAbout = req.body.aboutme;
User.findOne({username: req.decoded.username},function(err,mainUser){
if(err) throw err;
if(!mainUser){
res.json({success:false, message: 'no User found'});
}else{
if(newAbout){
if(mainUser.permission === 'admin'){
User.findOne({_id: editUser},function(err, user){
if(!user){
res.json({success:false, message: 'Now user found'});
} else{
user.aboutme = newAbout;
user.save(function(err){
if(err){
console.log(err);
} else{
res.json({success:true, message : 'Description about user has been Update'});
}
});
}
});
}else{
res.json({success:true, message:'Insufficient Permissions'});
}
}
if(newBlock){
if(mainUser.permission === 'admin'){
User.findOne({_id: editUser},function(err, user){
if(!user){
res.json({success:false, message: 'Now user found'});
} else{
user.block = newBlock;
user.save(function(err){
if(err){
console.log(err);
} else{
res.json({success:true, message : 'Successfully you blocked a user'});
}
});
}
});
}else{
res.json({success:true, message:'Insufficient Permissions'});
}
}
//here I used a lot if condition just to provide high security
if(newPermission) {
if(mainUser.permission === 'admin'){
User.findOne({_id: editUser},function(err, user){
if (err) throw err;
if(!user){
if(newPermission === 'user'){
if(user.permission === 'admin'){
if(mainUser.permission !== 'admin'){
res.json({success:false, message: 'Insufficient Permissions. You must be an admin to downgrade'});
} else{
user.permission = newPermission;
user.save(function(err){
if(err){
console.log(err);
}else{
res.json({success:true, message: 'Permissions have been Update'});
}
});
}
}
if(newPermission === 'admin'){
if (mainUser.permission === 'admin'){
user.permission = newPermission;
user.save(function(err){
if(err){
console.log(err);
}
else {
res.json({success:true, message:'Permissions have been Update'});
}
});
} else {
res.json({success:false, message:'Insufficient Permissions have been updated!!'});
}
}
}
}
});
}
else {
res.json({success:true, message:'Insufficient Permissions'});
}
}
}
});
});
in controller (This is my Angular post call:)
app.UpdateUsername = function(newAbout, valid){
app.errMsg = false;
app.disabled = true;
var userObject = {}; // Create a user object to pass to function
userObject._id = app.currentUser; // Get _id to search database
if(valid){
userObject.aboutme = $scope.newAbout; // Set the new name to the user
// Runs function to update the user's name
User.adminEditUser(userObject).then(function(data) {
// Check if able to edit the user's name
if (data.data.success) {
// $scope.alert = 'alert alert-success'; // Set class for message
app.successMsg = data.data.message;
// Set success message
// Function: After two seconds, clear and re-enable
$timeout(function() {
app.nameForm.aboutme.$setPristine(); // Reset name form
app.nameForm.aboutme.$setUntouched(); // Reset name form
app.successMsg = false; // Clear success message
app.disabled = false; // Enable form for editing
}, 2000);
} else {
//$scope.alert = 'alert alert-danger'; // Set class for message
app.errorMsg = data.data.message; // Clear any error messages
app.disabled = false; // Enable form for editing
}
});;
} else{
app.errorMsg = 'Please Ensure you filled form properly';
app.disabled = false
}
}
})
Html page:
<form name="edit.nameForm" ng-show="edit.phase1" novalidate ng-submit="edit.UpdateUsername(newAbout, edit.nameForm.aboutme.$valid)">
<!--Username-->
<div class="col-md-12">
<div class="form-group">
<div ng-class="{ 'has-success':(edit.nameForm.aboutme.$valid && !edit.nameForm.aboutme.$pristine), 'has-error':(!edit.nameForm.aboutme.$valid && !edit.nameForm.aboutme.$pristine) || (!edit.nameForm.aboutme.$valid && edit.nameForm.$submitted) }">
<label class="label label-primary">About User</label>
<br>
<input ng-disabled="edit.disabled" class="form-control" type="text" id="test_id" name="aboutme" placeholder="Please Write 100 words about Youeself " ng-model="newAbout" ng-pattern="/^[A-Za-z ]+$/" ng-minlength="0" ng-maxlength="100" required/>
<p class="help-block" ng-show="(!edit.nameForm.aboutme.$pristine && edit.nameForm.aboutme.$error.required) ||
(edit.nameForm.$submitted && edit.nameForm.aboutme.$error.required)">This field is required</p>
<ul ng-show="(!edit.nameForm.aboutme.$pristine && edit.nameForm.aboutme.$error.pattern) ||
(!edit.nameForm.aboutme.$pristine && edit.nameForm.aboutme.$error.minlength) || (!edit.nameForm.aboutme.$pristine && edit.nameForm.aboutme.$error.maxlength)" class="help-block">
<li>Must not contain any numbers or special characters</li>
<li>You must write 100 words no more</li>
</ul>
</div>
</div>
</div>
<center>
<h5><button class="btn btn-primary btn-block" type="submit">Update</button></h5></center>
</div>
</form>
<div class="row show-hide-message" ng-show="edit.successMsg">
<div class="alert alert-success"> {{edit.successMsg}}</div>
</div>
<br>
<div class="row show-hide-message" ng-show="edit.errorMsg">
<div class="alert alert-danger">{{edit.errorMsg}}</div>
</div>
is service:
userFactory.adminEditUser = function(id) {
return $http.put('/sign/edit/', id);
}
More than two days I stuck up in these error So Does anyone have any idea why this might be happening? and what I must do? I am sure there is mistake but I don't know where

parsley.js: issue with custom validator

I have a custom validator as shown below...
window.Parsley
.addValidator('invalidwords', {
requirementType: 'regexp',
validateString: function(value, requirement) {
var wordval = value.split(" ");
$.each(wordval,function(idx,item) {
return !/^\b(?:Stadium|GT|BB|HB|Simul|VNOSE|LT|combination|LT1|SSGT|BW|HBS|simul|combo|2hbs|4d|lt2|theatre)\b$/i.test(item)
});
},
messages: {
en: 'Invalid words detected.'
}
});
Basically what I want is to check a string to see if it contains any of the words in my regex.
Before I added the each() function it would work for single words, but it wouldn't work when i entered in something like gt lt so I had to put them in an array and check each one.
It appears to work when I debug as it does return false, but it seems as though parsley isn't seeing it or something to that effect.
Here is how I am calling it...
<div class="col-sm-6 col-lg-6">
<div class="form-group">
<input type="text" name="company" data-parsley-group="eventinfo" id="Company" class="form-control" placeholder="Company" maxlength="60" tabindex="3" title="Company" parsley-trigger="keyup" data-parsley-invalidwords="" value="#request.args.company#">
</div>
</div>
I also tried changing requirementType: 'regexp', to requirementType: 'string',
Got it figured out. Had to do the return outside the loop. here is my final code.
window.Parsley
.addValidator('invalidwords', {
requirementType: 'regexp',
validateString: function(value, requirement) {
var wordval = value.split(" ");
var valid = true;
$.each(wordval,function(idx,item) {
console.log(item,/^\b(?:Stadium|GT|BB|HB|Simul|VNOSE|LT|combination|LT1|SSGT|BW|HBS|simul|combo|2hbs|4d|lt2|theatre)\b$/i.test(item));
if(/^\b(?:Stadium|GT|BB|HB|Simul|VNOSE|LT|combination|LT1|SSGT|BW|HBS|simul|combo|2hbs|4d|lt2|theatre)\b$/i.test($.trim(item))){
valid = false;
}
});
return valid;
},
messages: {
en: 'Invalid words detected.'
}
});

Resources