Cannot save a document in Mongoose - Validator required failed for path error - mongodb

Following is my schema:
var userSchema = new Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: false
}
});
Now, when I attempt to save a document of the above schema, I get the following error:
{ message: 'Validation failed',
name: 'ValidationError',
errors:
{ username:
{ message: 'Validator "required" failed for path username',
name: 'ValidatorError',
path: 'username',
type: 'required' } } }
The above is the error object returned by mongoose upon save. I searched for this error but could not understand what is wrong. The document that I am trying to save is as follows:
{
username: "foo"
password: "bar"
}
Any idea what this means? I searched the mongoose docs too but could not find anything under the validation section.

First, you are missing a comma (,) after foo.
Now, is { username: "foo", password: "bar" } JSON sent via http, our an actual object in your server-side code ?
If it is, try to console.log(youVariable.username) and see if it shows undefined or the value foo. If you see undefined, then your object is not parsed properly.
You can make sure that whom ever is sending the POST request is sending a "application/json" in the header, you could be receiving something else, thus your JSON isn't parsed to a valid javascript object.

Related

Mongoose 6 - How to get only the custom validation error message without the error?

const userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: [true, 'Email address is required'],
minlength: [4, 'Must be at least 4 characters long']
}
});
When I log the error I get:
User validation failed: email: Must be at least 4 characters long
How can I get only my custom message:
Must be at least 4 characters long
The only thing I do as of now is
const messageString = message.split(':');
messageString[3]
But is there a better way? I saw some solutions for this but its all for mongoose version 5 or less and it doesnt apply to version 6 as the error object has different properties.
On a side note (maybe this should be a seperate question) but as the error object is different now, how can I check if its a mongoose validation error? The err object doesnt come with it anymore.
Error: User validation failed: email: Must be at least 4 characters long
at ValidationError.inspect (/Users/... {
errors: {
email: ValidatorError: Must be at least 4 characters long
at validate (/Users/user/....
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: [Object],
kind: 'minlength',
path: 'email',
value: 'hgg',
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'User validation failed'
}
Also, I dont want to have to access the modal property 'email' when accessing any other property as in my errorhandler, I want to keep it reusable for other errors too

Unexpected <EOF> while using graphql

Getting EOF error every time at same line, changed code many times and even degraded to previous versions of graphql but no positive results.
My code is:
const graphql = require('graphql')
const _ = require('lodash')
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql
const users = [
{id: '1', firstName: 'Ansh', age: 20},
{id: '2', firstName: 'Ram', age: 21},
{id: '3', firstName: 'Sham', age: 20}
]
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: {type: GraphQLString},
firstName: {type: GraphQLString},
age: {type: GraphQLInt}
}
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: {id: {type: GraphQLString}},
resolve(parentValue, args) {
return _.find(users, {id: args.id})
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
})
Error is:
{
"errors": [
{
"message": "Syntax Error GraphQL request (30:1) Unexpected <EOF>\n\n29: \n30: \n ^\n",
"locations": [
{
"line": 30,
"column": 1
}
]
}
]
}
The issue is because the query you're passing might be empty.
For example:
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user { id } }"}'
works fine.
But if you make something like:
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": ""}'
You'll get unexpected < EOF >
Also, check GraphQL end of line issue.
I had comments in the schema.graphql file:
"""
Some comments
"""
I removed the comments and the Unexpected <EOF> error went away.
It's because there's no actual query so you get unexpected EOF (End of File).
Guessing that you're using GraphiQL (because your EOF message says line 30); you need to add a query on the left-hand panel of GraphiQL in the browser. Something which conforms to your RootQuery like:
{
user(id: "1") {
id,
firstName,
age
}
}
I got this error while trying to stitch my schema
the reason for this error was that I delcared a type but didn't implemet it, had empty body, for example:
type User {
}
implementing the type fixed it
It looks like if we are doing the schema-first approach, but we do not have any .graphql files in your project/empty. I added this and the error went away:
src/example.graphql
type Query {
hello: String
}
The "GraphQLError: Syntax Error: Unexpected " error is coming from the graphql package. It looks like #nestjs/graphql is assuming that there will always be at least one .graphql file, so this is probably a bug to try and parse an empty schema vs display a more developer-friendly message or ignore it.
In most cases passing an empty query is caused to this error.
To avoid this try this in your graphiql
query {
user {
fields you need to retrieve
}
}
This is because your graphql.gql looks like this:
# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------
directive #key(fields: String!) on OBJECT | INTERFACE
directive #extends on OBJECT | INTERFACE
directive #external on OBJECT | FIELD_DEFINITION
directive #requires(fields: String!) on FIELD_DEFINITION
directive #provides(fields: String!) on FIELD_DEFINITION
One thing you can do is create a dummy resolver.
// src/graphql/resolvers/user.resolver.ts
import { Resolver, Query } from '#nestjs/graphql';
import { User } from 'models/User.model';
#Resolver(() => User)
export class UserResolver {
#Query(() => User)
async ids() {
return [];
}
}
and create a graphql model:
// src/graphql/models
import { Field, ObjectType } from '#nestjs/graphql';
#ObjectType()
export class User {
#Field()
createdAt: Date;
}
And make sure that resolver is imported by a module and the module is added to App.module
This should fix it!
In my case on the frontend side (Angular), since I just wanted to observe something, I have this code:
I got this error:
Error: Unexpected <EOF>.
and I made it comment-line and the error was gone
How to fix it: Go to node_mudules > graphql > syntaxError.js and delete all comments from this file and the error should be gone.

Getting "Invalid exit definition" on Compilation of Sails Helper (Sails v1.0)

I'm getting the error
Invalid exit definition ("success"). Must be a dictionary-- i.e. plain JavaScript object like `{}`.
Invalid exit definition ("error"). Must be a dictionary-- i.e. plain JavaScript object like `{}`.
when doing sails lift. The error is on getRole.js
module.exports = {
friendlyName: 'Get Role',
description: '',
inputs: {
user_id: {
friendlyName: 'User Id',
description: 'The ID of the user to check role',
type: 'string',
required: true
}
},
exits: {
success: function (role){
return role;
},
error: function (message) {
return message;
}
},
fn: function (inputs, exits) {
User.findOne({ id: inputs.user_id } , function (err, user) {
if (err) return exits.err(err);
return exits.success(user.role);
});
}
};
This is a new error, and looking at my git, nothing has changed in my code since it successfully compiled. I understand the Sails version (v1.0) I'm using in beta, so I'm taking that into account.
Exits cannot be defined as functions. There is a special syntax (Machine Spec) to define exits. In your example this should work:
exits: {
error: {
description: 'Unexpected error occurred.',
},
success: {
description: 'Role was succesffuly fetched'
}
},
You can read more info about helper exits here: https://next.sailsjs.com/documentation/concepts/helpers
May changes occur on the last release 1.0.0-38. I've not checked underneath yet, but the way to execute helpers changed: on .exec() I get errors. Now, use .switch();

Sails.js controller not inserting into Mongo database

I've been all over SO and Sailsjs.org trying to figure out what's going wrong, and to no avail. Just trying to learn the basics of SailsJS. I have a UserController, whose create() method gets called when a POST request is sent to /user.
create: function (req, res) {
var params = req.params.all();
User.create({
name: params.FirstName + ' ' + params.LastName,
email: params.Email,
password: params.Password,
jobTitle: params.JobTitle
}).exec(function createCB(err,created)
{
created.save(function(err)
{
// No error . . . still nothing in db
});
return res.json({name: created.name, jobTitle: created.jobTitle, email: created.email, password: created.password});
});
}
No errors here. All the request params are coming in fine and going back to the client without trouble. But nothing is actually being written to the database.
In development.js:
connections: {
mongo: {
adapter: 'sails-mongo',
host: 'localhost',
port: 27017,
// user: 'username',
// password: 'password',
database: 'sails_test'
}
},
models: {
connection: 'mongo'
}
I've tried this with the above both there in development.js, as well as separately in connections.js and models.js, respectively. No difference.
In User.js:
attributes: {
FirstName : { type: 'string' },
LastName : { type: 'string' },
Email : { type: 'string' },
Password : { type: 'string' },
JobTitle : { type: 'string' }
}
My front end request:
$.ajax({
method: 'post',
url: '/user',
data: {
FirstName: 'Yo',
LastName: 'Momma',
Email: 'yourmom#yourdadshouse.com',
Password: 'YouWish123',
JobTitle: 'Home Maker Extraordinaire'
},
success: function (sailsResponse)
{
$('#result').html(sailsResponse).fadeIn();
},
error: function()
{
console.log('error');
}
});
Again, none of this is producing an explicit error. There is just nothing being inserted into the database. Or if there is, I don't know how to find it. I've confirmed the existence of this db in the mongo shell, thusly:
show dbs
My db, sails_test shows up in the list. And I've confirmed that there isn't anything in it like so:
db.sails_test.find()
I would very much appreciate some guidance here :)
Update:
Turns out the data is being written just fine. I'm just unable to query the database from the command line. I confirmed this by first creating a sample user, and then using Waterline's findOne() method:
User.findOne({FirstName: params.FirstName}).exec(function (err, user) {
if (err) {
res.send(400);
} else if (user) {
return res.json({firstName: user.FirstName, lastName: user.LastName, jobTitle: user.JobTitle, email: user.Email, password: user.Password});
} else {
return res.send('no users match those criteria');
}
});
The above works as expected. So my problem now is simply that I cannot interact with the database from the command line. db.<collectionName>.find({}) produces nothing.
This was simply a failure to understand the MongoDb docs. I read db.collection.find({}) as DatabaseName.CollectionName.find({}), when you literally need to use db. So if my database is Test, and my collection is Users, the query is use Test, and then db.Users.find({}).
Also of note, 3T Mongo Chef is a pretty rockin' GUI (graphical user interface) for nosql databases, and it's free for non-commercial use.

"email" validation rule crash sails server - Mongo with Sails.js

while the email validation rule fails on module of the sails.js, the server is crashing.
Here the snippet of my module:
// The user's email address
email: {
type: 'string',
email: true,
required: true,
unique: true
},
And the error as below :
err: Error (E_VALIDATION) :: 1 attribute is invalid
at WLValidationError.WLError (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\error\WLError.js:26:15)
at new WLValidationError (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\error\WLValidationError.js:20:28)
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\query\validate.js:45:43
at allValidationsChecked (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\core\validations.js:203:5)
at done (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:135:19)
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:32:16
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\core\validations.js:184:23
at done (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:135:19)
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:32:16
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\core\validations.js:157:64
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:125:13
at Array.forEach (native)
at _each (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:46:24)
at Object.async.each (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:124:9)
at validate (C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\waterline\lib\waterline\core\validations.js:156:11)
at C:\Users\yuri\AppData\Roaming\npm\node_modules\sails\node_modules\async\lib\async.js:125:13
Invalid attributes sent to User:
• email
• undefined should be a email (instead of "admin#gmailasd", which is a string)
The correct way to declare an email field is like this :
email: {
type: 'email',
required: true,//Email field will be required for insert or update
unique: true //Insert or update will crash if you try to insert duplicate email
},
You can see all different attribut types here http://sailsjs.org/documentation/concepts/models-and-orm/attributes
If you want to catch insert/update errors you can do this on your controller :
MyModel.create({email:email}).exec(function(err, model)
{
if(err)
{
//Check if it's a validation error or a crash
if(err.code == "E_VALIDATION")
sails.log.debug("valid fail, check form");
else
sails.log.debug("crash");
}
else
{
//do what you want to do with the data
}
});
Her the answer.
Thanks to jaumard, i found the problem.
I used undefined field in error, without checking if exists before
err.originalError.code but it was undefined.
So the correct way is :
err.originalError && err.originalError.code && err.originalError.code === 11000
and not
err.originalError.code === 11000.
Previous versions of Sails recommended that email validation was achieved like this
email: {
type: 'string',
email: true,
required: true
},
The current version should be like this
email: {
type: 'email',
required: true
},