I am trying to insert a new message into the database using expressjs and mongoose.
But I'm getting a ValidationError in the process. The following is printed at the console.
error while storing message ::: ValidationError: user: Cast to
Embedded failed for value "[]" at path "user"
The code is as follows:
socketAPI.io.on('connection', function(socket){
socket.on('chat-sent', function(param) {
ChatUser.find({username : param.username}).then(async (usr)=>{
if(usr){
try{
var mess = new GroupMessage();
mess.group = (await Group.findOne({name : groupName}));
mess.message = param.message;
mess.user = usr;
mess.save((err)=>{
if(err){
console.log('error while storing message ::: '+err);
}
else{
console.log('message succesfully stored');
}
});
}catch(err){
console.log('error collecting group ::: '+err);
}
}
});
socket.emit('group-message-handled', { user : param.username, message : param.message});
});
});
The insertion code makes use of the following models:
var userSchema = new mgoose.Schema({
username : {
type : String,
required : true,
unique : true,
maxlength : [15, 'Too long username. Max 15 allowed']
},
name : String
});
var groupSchema = new mgoose.Schema({
name : {
type : String,
required : true,
unique : true
},
categories : [String]
});
var groupMessageSchema = new mgoose.Schema({
user : userSchema,
group : groupSchema,
message : {
type : String,
required : true,
minlength : 1
}
});
var ChatUser = mgoose.model('ChatUser', userSchema);
var Group = mgoose.model('Group', groupSchema);
var GroupMessage = mgoose.model('GroupMessage', groupMessageSchema);
What causes this error and how can I fix it?
Related
I would like to add new field into json already have in mongoDB Cosmos like this
{
"_id" : "6396cde306fd2d1088d584e4",
"userName" : "user-20526"
}
Now I would like to add a others field like this bellow userName field:
{
"_id" : "6396cde306fd2d1088d584e4",
"userName" : "user-20526",
"others": [
{
"address" : "city",
"phone" : "12345676543"
}
]
}
I user this function to do that thing, with updateDocument but it's not works for me:
const updateDocuments = async (value, condition, collectionName) => {
const DATABASE_COLLECTION_NAME = collectionName;
if (!db)
throw Error('findDocuments::missing required params');
const collection = await db.collection(DATABASE_COLLECTION_NAME);
const filter = { condition };
const filterJSON = JSON.parse("{" + filter.condition + "}");
const options = { upsert: true };
// get value (condition) and convert it to correct JSON format before call it in update variable
const getValue = { value }
const valueJSON = JSON.parse("{" + getValue.value + "}");
const updateDoc = {
$set: valueJSON
};
return await collection.updateOne(filterJSON, updateDoc, options);
}
The above function only works when we update one field that already have in data, the example I would like to update userName data, then that function is work, If I use that function to add new one then it's not, not add new one, how can I create more to add new field as what I expected before
anyone please help me
I'm having difficulty creating the routes to send to MongoDB.
When I return user, it returns the full database. This goes for using User or 'user'.
User is a model
let User = require('../models/user.model');
User.findById(req.params.id)
.then(user => {
if (!user)
res.status(404).send("data is not found");
else
for(var key in req.body.proposal) {
//res.send(user.proposal)
//res.send(user)
//res.send(User.username)
user.proposal.insertOne(
{
"uid" : req.body.proposal[key].uid,
"clientEmail" : req.body.proposal[key].clientEmail,
"summary" :req.body.proposal[key].summary,
"terms" :req.body.proposal[key].terms,
"form" :req.body.proposal[key].form
} //update
)
}
user.save()
.then(user => res.json(user))
.catch(err => res.status(400).json('Error: ' + err));
})
.catch(err => res.status(400).json('Error: ' + err));
});
Thank you in advanced!
It should be something like this :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
user.proposal = proposalArr;
user.save().............
You can't use .insertOne on result of database query, it's a function of mongoose model to insert new document to collection but not to insert new fields to objects. You need to do just like adding new fields to json object using .js code, but mongoose will keep track of object's changes & when you use .save() it can update the document in collection with all those changes.
Instead of two DB calls, you can do that in one call, Check : .findByIdAndUpdate() & try below sample code :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
User.findByIdAndUpdate(
req.params.id,
{
proposal: proposalArr
},
{ new: true }
)
.then(user => {
if (!user) res.status(404).send("data is not found");
res.json(user);
})
.catch(err => res.status(400).json("Error: " + err));
I was wondering if it was possible to create a login system using a webservice as I need to add a login system in my app in Smartface App Studio?
Thanks
Yes, it's possible.
One of the possible solutions is to get the user's information from a server and compare the password that the user typed and the one that came from the server, if it's equal, log in. I personally use Firebase as my server, so I save user's object name as his email, so every time I want to get this user's object, I make a GET request with his email in the URL.
Eg.
var webclient = new SMF.Net.WebClient({
URL : "https://exampleapp.firebaseio.com/Users/example#example.com",
httpMethod : "GET",
...
onSyndicationSuccess : function(e){
var response = JSON.parse(e.responseText);
if(response.password === Pages.Page1.UserPassword.text){
//Login
} else {
alert("Wrong Password!");
}
}
});
Hope that helps! :)
EDIT
var ROOT_URL = "https://exampleapp.firebaseio.com/"; //Change to your Firebase App
var FIREBASE_CREDENTIAL = "yourAppSecret"; //Change to your Firebase App Secret
var firebase = {
register : function (email, password, callback) {
var emailReplace = email.replace(/\./g, ",");
var beginRegister = function () {
requestObj = {
"email" : email,
"password" : password
};
var requestJSON = JSON.stringify(requestObj);
var wcRegister = new SMF.Net.WebClient({
URL : ROOT_URL + "Users/" + emailReplace + ".json?auth=" + FIREBASE_CREDENTIAL,
httpMethod : "POST",
requestHeaders : ['Content-Type:application/json', 'X-HTTP-Method-Override:PATCH'],
requestBody : requestJSON,
onSyndicationSuccess : function (e) {
//Registered, do something
callback();
},
onServerError : function (e) {
//Do something
}
});
wcRegister.run(true);
};
var isTaken = new SMF.Net.WebClient({
URL : ROOT_URL + "Users/" + emailReplace + ".json?auth=" + FIREBASE_CREDENTIAL,
httpMethod : "GET",
requestHeaders : ["Content-Type:application/json"],
onSyndicationSuccess : function (e) {
var response = JSON.parse(isTaken.responseText);
if (response !== null) {
//Email is taken, do something
} else {
beginRegister(); //Email is not taken, continue
}
},
onServerError : function (e) {
//Server Error, do something
}
});
isTaken.run(true);
},
login : function (email, password, callback) {
var emailReplace = email.replace(/\./g, "%2C");
var wcLogin = new SMF.Net.WebClient({
URL : ROOT_URL + "Users/" + emailReplace + ".json?auth=" + FIREBASE_CREDENTIAL,
httpMethod : "GET",
requestHeaders : ["Content-Type:application/json"],
onSyndicationSuccess : function (e) {
var responseText = JSON.parse(wcLogin.responseText);
if (responseText) {
if (password === responseText.password) {
//User logged, do something
callback();
} else {
//Password is wrong, do something
}
} else {
//User doesn't exist, do something
}
},
onServerError : function (e) {
//Server error, do something
}
});
wcLogin.run(true);
}
}
Put this code somewhere in global scope (in an empty space) and when you want the user to login, use firebase.login(someEmail, somePassword, callback), where callback is a function that you want to run when the login is finished. And when you want to register a user, use firebase.register(someEmail, somePassword, callback).
OBS. Just remember to change the auth value in Firebase rules.
I have a mongo collection that is created outside of Meteor that holds user info of people who want access to my app. It looks like this in MongoVue-
**tmpUsers**
/* 5 */
{
"_id" : ObjectId("54c7ae456587e23335915948"),
"email" : "trial#domain.com",
"first" : "Trial User",
"type" : "trial",
"active" : "Yes"
}
When I try to read this I get basically an empty collection structured like this -
collection:
d_docs: d._IdMap_..........
Here's my code -
**client**
var type = "";
var tmpCursor = tmpUsers.find({"email": Meteor.user().emails[0].address});
tmpCursor.forEach(function(rec) {
type = rec.type
});
Meteor.call("updateProfile", Meteor.userId(), type);
**server**
Meteor.methods({
"updateProfile": function(id, value){
Meteor.users.update({"_id": id}, {$set: {"profile.acctType": value}});
}
})
How would I update the client side code to read the type from tmpUsers?
Update:
Here is where I insert the record from outside of Meteor -
try {
$mongoDb = $mongoConn->abcdefg;
$collection = $mongoDb->tmpUsers;
$userInfo = array("email" => $_POST['email'], 'first' => $first,"type" => $_POST['type'], 'active' => $activation);
$collection->insert($userInfo);
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
Try with this.
Tracker.autorun(function(){
Meteor.subscribe('tmpUsers',function(){
var finde = tmpUsers.find({email:Meteor.user().emails[0].address}).count();
if (finde === 1){
console.log("found email");
} else{
console.log("not email found")
}
});
});
I. This Works:
//dbModuleSchema.js
var mongoose = require('mongoose');
function getDbModuleSchema() {
var dbModuleSchema = mongoose.Schema({
roles : [rolesSchema] <--------------------------- from local variable
};
///////////////////////////////////
// local variable for roles schema
///////////////////////////////////
var rolesSchema = mongoose.Schema({ //<------------ local variable
name : {type : String},
description : {type: String}
};
return dbModuleSchema;
};
exports.getDbModuleSchema = getDbModuleSchema;
II. This doesn't:
//dbModuleSchema.js
var mongoose = require('mongoose'),
securitySchema = require('./../security/securitySchema');
function getDbModuleSchema() {
var dbModuleSchema = mongoose.Schema({
roles : [securitySchema.getRolesSchema] <-- from separate securitySchema module
}
return dbModuleSchema;
};
exports.getDbModuleSchema = getDbModuleSchema;
//securitySchema.js
var mongoose = require('mongoose');
function getRolesSchema() { //<------ separate securitySchema module
var rolesSchema = mongoose.Schema({
name : {type : String},
description : {type: String}
};
return rolesSchema;
};
exports.getRolesSchema = getRolesSchema;
III. With this as my json:
{
"moduleStyleId" : "style-0",
"name" : "My Dashboard",
"roles" : [{"name" : "Employee", "description" : "Everyone"}]
},
IV. The difference between I & II.
In I, I declared the roles schema in the same module, In II, I refactored it out to it's own seperate module and called its function within the moduleSchema.
Am I not allowed to do that?
Figured it out, the key is to pass the remote module to a variable first:
var mongoose = require('mongoose'),
securitySchema = require('../security/securitySchema');
function getDbModuleSchema() {
var rolesSchema = securitySchema.getRolesSchema(); <--- pass remote schema to variable first
var dbModuleSchema = mongoose.Schema({
roles : [rolesSchema],
};
return dbModuleSchema;
};
exports.getDbModuleSchema = getDbModuleSchema;
Thanks, guys, couldn't have done it w/o "youse"! ;)