How to import functions from another file in NodeJS? - javascript

I'm new in NodeJS, and I'm struggling a little bit on this. I'm using Express and to validate the data, I'm using Celebrate.
I've got a route.js file, where I make a POST request, using a function from another file to do so (it's the create function, from MyController. It works fine! But when I try to do the same thing to my validator, it doesn't work.
So let's take a look at the code.
The route.js file:
const express = require("express");
const MyController = require("./controllers/MyController");
const MyValidator= require("./validators/MyValidator");
const routes = express.Router();
routes.post("/path", MuValidator.validateCreate, MyController.create);
The MyValidator file:
module.exports = {
validateCreate() {
celebrate({
[Segments.HEADERS]: Joi.object({
authorization: Joi.string().required(),
}).unknown(),
[Segments.BODY]: Joi.object().keys({
userId: Joi.string().required(),
title: Joi.string().required(),
description: Joi.string().required(),
value: Joi.number().required(),
dueDate: Joi.string().required(),
}),
});
},
}
IMPORTANT:
I only get this working, if I write the validation code directly on my route, like this:
routes.post(
"/path",
celebrate({
[Segments.HEADERS]: Joi.object({
authorization: Joi.string().required(),
}).unknown(),
[Segments.BODY]: Joi.object().keys({
userId: Joi.string().required(),
title: Joi.string().required(),
description: Joi.string().required(),
value: Joi.number().required(),
dueDate: Joi.string().required(),
}),
}),
MyController.create
);

the problem is that the celebrate function creates and returns a middleware, so the middleware returned by the celebrate function must be passed as second parameter to the post but you're passing a function that execute the celebrate method instead, so validateCreate should be:
module.exports = {
validateCreate: celebrate({...})
}

I think you did something wrong with module exports
try something like this:
module.exports = {
validateCreate: function() {},
otherMethod: function() {},
};

Related

Joi validate one of two schemas

I have a simple object with few fields that I would like to validate. I wish to allow or a specific validation schema or that all of the properties have empty values
I created the following two schemas:
const nonEmptyUserInfoValidationSchema = Joi.object({
url: Joi.string().uri().required(),
username: Joi.string().required().min(usernameMinLength),
password: Joi.string().required().min(passwordMinLength),
});
const emptyUserInfoValidationSchema = Joi.object({
url: Joi.string().empty().required(),
username: Joi.string().empty().required(),
password: Joi.string().empty().required(),
});
I wish to create schema that validates if emptyUserInfoValidationSchema or nonEmptyUserInfoValidationSchema is applied but I can't figure out how to do it, any suggestions?
allowed:
{url:"http://some.url", username:"some username", password:"some password"}
{url:"", username:"", password:""}
not allowed:
{url:"http://some.url", username:"", password:""}
Well I finally found what I was looking for joi.alternatives:
export const ansibleInfoValidationSchema = Joi.alternatives(emptyUserInfoValidationSchema , nonEmptyUserInfoValidationSchema );
seems to do the trick
You use the .keys().and() to specify peers. This means that none of the fields specified in the .and() will exist without each other. Hence should be used as so:
const schema = Joi.object({
url: Joi.string().uri(),
username: Joi.string().min(usernameMinLength),
password: Joi.string().min(passwordMinLength)
}).keys().and('url', 'username', 'password');
I hope this helps you can use the when condition in Joi
var schema = Joi.object({
url : Joi.any().when('username',{
is: Joi.empty(),
then: Joi.empty().required(),
otherwise: Joi.string().required()
}),
username: Joi.when('password',{
is: Joi.empty(),
then: Joi.empty(),
otherwise: Joi.string().required().min(usernameMinLength)
})
});
here's a link to when docs Joi When Condtion

Joi validate 2 schemas conditionally - Invalid schema content

I'm trying to add conidial schema according of the value of the isCat field in the request body, here is what I have so far:
ror [ERR_ASSERTION]: Invalid schema content` error.What am I missing? Thanks.
Try this
Joi.object({
params: Joi.object({
id: Joi.number().required().integer().min(1),
}),
body: Joi.object({
code: Joi.string().required(),
}).when(Joi.ref("$isValid"), {
is: Joi.equal(true),
then: Joi.object({
body: Joi.object({
...entity,
}),
}),
otherwise: Joi.object({
body: Joi.object({
...put,
}),
}),
}),
});
Verify the reference given by you is right Joi.ref("$isValid").
If you provide right reference, this schema will work as you expect.

mongoose Model.save() only returns { _id, __v }

I know this question has been asked before but I feel like I'm doing everything right and I'm still having an issue. I want to save an item from a form into my mongodb collection using mongoose.
My schema:
// stationmodel.js
export const StationSchema = new mongoose.Schema({
"FDID": String,
"Fire dept name": String,
"HQ addr1": String,
"HQ city": String,
"HQ state": String,
"HQ zip": Number,
"HQ phone": String,
"Dept Type": String,
"Organization Type": String,
"Website": String,
"Number Of Stations": Number,
"Primary agency for emergency mgmt": Boolean,
}, {collection: "FEMA_stations"})
In my express app:
// in routes.js
const StationSchema = require('./stationmodel')
const Station = mongoose.model('Station', StationSchema, 'FEMA_stations')
const addstation = (req, res) => {
console.log(req.body)
const newStation = new Station(req.body)
newStation.save( function(err){
if (err) { console.error(err) }
console.log('newStation after save', newStation)
})
}
const routes = app => {
app.route('/api/addstation')
.post(addstation)
}
export default routes
// in index.js
import routes from './routes'
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
routes(app)
In my front end code, calling to the backend in a redux action:
fetch('/api/addstation', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(stationToAdd)
})
When I console.log(req.body) on my back end, I get the data I'm expecting. It looks something like this:
{
FDID: '202020',
'Fire dept name': 'Some Fire Department',
'HQ addr1': 'Some address',
'HQ city': 'San Dimas',
'HQ state': 'CA',
'HQ zip': 99999,
'HQ phone': '5555555555',
'Dept Type': 'Career',
'Organization Type': 'State',
Website: '',
'Number Of Stations': 0,
'Primary agency for emergency mgmt': true,
}
But when I console.log my newStation that I'm trying to .save(), all I get is a response like this:
{ _id: 5efe29911ea067248f3c39a0, __v: 0 }
I know other people had issues with their schema, their model, making sure that they're truly connected to their mongodb collection, or making sure that the request is made with the application/json header, but I feel I have all those things right. The code was pieced together from a much more modularized app to try to cut the fat and present the core issue, so let me know if I'm missing any glaring information.
What might be going wrong here? Why is the data from req.body not making it into my new document that I'm trying to save to the collection? Thanks for reading.
You are mixing es6 module import/export with Node.js CommonJS require.
In stationmodel.js You are using a "named export"
export const StationSchema = new mongoose.Schema(...
But in routes.js you are using CommonJS require
const StationSchema = require('./stationmodel')
Which is likely to be an empty object. So the following line will create a model with an "empty" schema
const Station = mongoose.model('Station', StationSchema, 'FEMA_stations')
The solution
use named import instead
import { StationSchema } from './stationmodel'
TIP:
Since you are already name the file stationmodel.js, which suggests it's a model. You can put the following in stationmodel.js directly to prevent the model from getting incorrect schema
export const Station = mongoose.model('Station', StationSchema, 'FEMA_stations')

Use Jest to test an API endpoint and its response

I want to use jest to test an API endpoint to check if it returns a response and if the JSON contains the parameter keys that I need.
My function looks like the following:
export function getFiveDayWeatherByCoordinates(id) {
let url = FORECAST_ID_URL(id);
return fetch(url)
.then(response => response.json())
.then(data => {
return data;
})
.catch(err => console.log(err));
}
It returns a JSON with a set of parameters, I will post only a snapshot:
{
cnt: 14,
cod: "200",
city: {
coord: {lat: 38.7169, lon: -9.1333},
country: "PT",
id: 8012502,
name: "Socorro",
population: 0,
timezone: 3600,
}
Every tutorial that I see until now says to mock the response, but I want to test the actual API.
I would suggest using Frisby.js to test the API responses. It's a great test framework for API testing that runs in Jest. I've used it numerous times to write API and backend integration tests. Although, I typically keep these test suites separate from my UI unit tests.
Here's an example:
it('should return weather coords', async () => {
return frisby
.get(`${global.apiUrl}/my-weather-endpoint`)
.expect('status', 200)
.expect('jsonTypes', Joi.object({
cnt: Joi.number().required(),
cod: Joi.string().required(),
city: Joi.object({
coord: Joi.object({
lat: Joi.number().required(),
lon: Joi.number().required()
}),
country: Joi.string().required(),
id: Joi.number().required(),
name: Joi.string().required(),
population: Joi.number().required(),
timezone: Joi.number().required()
}).required()
});
});
Frisby also encourages the use of the Joi validation framework (it's already included in the npm package).

NodeJS joi returns error = null, even though error should occur

I'm running NodeJS with joi, and are trying to validate IBM Watson IoT config object.
This is my schema:
const schema = {
body: {
config: Joi.object().keys({
org: Joi.string().required(),
type: Joi.string().required(),
id: Joi.string().required(),
domain: Joi.string().required(),
'auth-method': Joi.string().required(),
'auth-token': Joi.string().required()
}).required()
}
};
And this is my check:
Joi.validate(req.body, schema, { allowUnknown: true }, (err, value) => {
console.log(err);
});
This returns null as error which indicates no error, but this is even if I haven't POSTed any parameters to my body.
Basically I want to make sure the body of my HTTP POST contains valid JSON object like so:
config = {
"org" : "organization",
"id" : "deviceId",
"domain": "internetofthings.ibmcloud.com",
"type" : "deviceType",
"auth-method" : "token",
"auth-token" : "authToken"
};
You're not passing Joi object to the validate function, you should be passing schema.body.config instead of schema. If body and config is supposed to be part of the validation, you should wrap them with Joi.Object the same way you did for all the keys inside config.

Categories