Cast only what is defined in the schema and strip out extra fields - Yup - yup

I have this schema:
yup.object().shape({
name_first: yup.string().required().label("Name First").meta({ initial: "" }),
name_last: yup.string().required().label("Name Last").meta({ initial: "" }),
mobile: yup
.number()
.typeError("must be a number")
.integer()
.positive()
.test("is-mobile", "${path} is not a valid mobile number", (value, context) => {
var strValue = value.toString();
if (strValue.length !== 8 || strValue.charAt(0) !== "9" || strValue.charAt(0) !== "7") {
return false;
} else {
return true;
}
})
.label("Mobile")
.meta({ initial: "" }),
email: yup.string().email().notRequired().label("Email address").meta({ initial: "" }),
gender: yup.mixed().oneOf(["m", "f"]).required().label("Gender").meta({ initial: "" }),
birth_date: yup.date().required().min(new Date(1900, 0, 1)).label("Birth Date").meta({ initial: null }),
preferred_language: yup.mixed().oneOf(["ar", "en"]).required().label("Preferred Language").meta({ initial: "" }),
newsletter: yup.boolean().required().label("Subscribe to Newsletter").meta({ initial: true }),
disabled: yup.boolean().required().label("Disabled").meta({ initial: false }),
});
I have this data object:
{
addresses: (75) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
birth_date: Wed Sep 23 2020 00:00:00 GMT+0400 (Gulf Standard Time) {}
created_at: "2020-09-23T13:57:24.156706"
disabled: false
email: "user#example.com"
email_confirmed: false
gender: "m"
id: 1
mobile: 99009900
mobile_confirmed: true
name_first: "string"
name_last: "string"
newsletter: true
preferred_language: "ar"
updated_at: "2020-09-23T13:57:24.156713"
}
And I want to cast this object but the casting does not strip out the extra fields that are not defined in the schema which are addresses, updated_at and created_at.
How can I do this automatically without specifically stripping out those field?

I found the solution:
schema.cast(dataObject, { stripUnknown: true})

Related

i am getting error like this how to resolve?

xhr.js:247 POST http://localhost:5000/questions net::ERR_CONNECTION_REFUSED
AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
code:"ERR_NETWORK"
config
:
{transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}
message
:
"Network Error"
name
:
"AxiosError"
request
:
XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
stack
:
"AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:54654:14)"
[[Prototype]]
:
Error

Do I need to connect to Mongo over and over again?

I am making a discord bot. When I was using java, I saved the data to mongo by creating different databases for each server my bot is in but on javascript I can only use one database.
And the only database it lets me connect/see is test database, other than that it shows everything as undefined.
And Mongo js docs tell me to connect to database over and over again but when using java I just connected on bot launch and was able to use it whenever I want. I tried all the examples I could find on stackoverflow but none of them helped me at all.
app.js :
require("./handler/mongo")();
client.on("ready", () => {
console.log(global.mongoclient.db("574612262275252231").collection("settings").find({}));
}
mongo.js:
const mongo = require('mongodb').MongoClient;
module.exports = function(){
mongo.connect(uri, (err, client) => {
if(err) throw err;
global.mongoclient = client;
console.log("a");
});
}
console output:
a
Cursor {
_readableState: ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
readable: true,
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
operation: FindOperation {
options: {
skip: 0,
limit: 0,
raw: undefined,
hint: null,
timeout: undefined,
slaveOk: true,
readPreference: [ReadPreference],
db: [Db],
promiseLibrary: [Function: Promise]
},
ns: MongoDBNamespace {
db: '574612262275252231',
collection: 'settings'
},
cmd: {
find: '574612262275252231.settings',
limit: 0,
skip: 0,
query: {},
raw: undefined,
hint: null,
timeout: undefined,
slaveOk: true,
readPreference: [ReadPreference]
},
readPreference: ReadPreference { mode: 'primary', tags: undefined },
cursorState: {
cursorId: null,
cmd: [Object],
documents: [],
cursorIndex: 0,
dead: false,
killed: false,
init: false,
notified: false,
limit: 0,
skip: 0,
batchSize: 1000,
currentLimit: 0,
transforms: undefined,
raw: undefined
}
},
pool: null,
server: null,
disconnectHandler: undefined,
bson: undefined,
ns: '574612262275252231.settings',
namespace: MongoDBNamespace { db: '574612262275252231', collection: 'settings' },
cmd: {
find: '574612262275252231.settings',
limit: 0,
skip: 0,
query: {},
raw: undefined,
hint: null,
timeout: undefined,
slaveOk: true,
readPreference: ReadPreference { mode: 'primary', tags: undefined }
},
options: {
skip: 0,
limit: 0,
raw: undefined,
hint: null,
timeout: undefined,
slaveOk: true,
readPreference: ReadPreference { mode: 'primary', tags: undefined },
db: Db {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s: [Object],
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter],
[Symbol(kCapture)]: false
},
promiseLibrary: [Function: Promise]
},
topology: ReplSet {
_events: [Object: null prototype] {
authenticated: [Function (anonymous)],
error: [Array],
timeout: [Array],
close: [Array],
parseError: [Array],
reconnect: [Array],
commandStarted: [Function (anonymous)],
commandSucceeded: [Function (anonymous)],
commandFailed: [Function (anonymous)],
serverOpening: [Function (anonymous)],
serverClosed: [Function (anonymous)],
serverDescriptionChanged: [Function (anonymous)],
serverHeartbeatStarted: [Function (anonymous)],
serverHeartbeatSucceeded: [Function (anonymous)],
serverHeartbeatFailed: [Function (anonymous)],
topologyOpening: [Function (anonymous)],
topologyClosed: [Function (anonymous)],
topologyDescriptionChanged: [Function (anonymous)],
joined: [Function (anonymous)],
left: [Function (anonymous)],
ping: [Function (anonymous)],
ha: [Function (anonymous)],
connectionPoolCreated: [Function (anonymous)],
connectionPoolClosed: [Function (anonymous)],
connectionCreated: [Function (anonymous)],
connectionReady: [Function (anonymous)],
connectionClosed: [Function (anonymous)],
connectionCheckOutStarted: [Function (anonymous)],
connectionCheckOutFailed: [Function (anonymous)],
connectionCheckedOut: [Function (anonymous)],
connectionCheckedIn: [Function (anonymous)],
connectionPoolCleared: [Function (anonymous)],
open: [Function],
fullsetup: [Function],
all: [Function]
},
_eventsCount: 35,
_maxListeners: Infinity,
s: {
coreTopology: [ReplSet],
sCapabilities: [ServerCapabilities],
tag: undefined,
storeOptions: [Object],
clonedOptions: [Object],
store: [Store],
options: [Object],
sessionPool: [ServerSessionPool],
sessions: Set(0) {},
promiseLibrary: [Function: Promise]
},
[Symbol(kCapture)]: false
},
cursorState: {
cursorId: null,
cmd: {
find: '574612262275252231.settings',
limit: 0,
skip: 0,
query: {},
raw: undefined,
hint: null,
timeout: undefined,
slaveOk: true,
readPreference: [ReadPreference]
},
documents: [],
cursorIndex: 0,
dead: false,
killed: false,
init: false,
notified: false,
limit: 0,
skip: 0,
batchSize: 1000,
currentLimit: 0,
transforms: undefined,
raw: undefined
},
logger: Logger { className: 'Cursor' },
s: {
numberOfRetries: 5,
tailableRetryInterval: 500,
currentNumberOfRetries: 5,
state: 0,
promiseLibrary: [Function: Promise],
explicitlyIgnoreSession: false
},
[Symbol(kCapture)]: false
}
And Mongo js docs tell me to connect to database over and over again
Those are simply examples. You can have a global client if you like (which would make sense for real applications).

Can make post request to localhost using node-fetch, but unable to do so using Axios

I have tried making the same post request using node-fetch and axios.
var fetch = require('node-fetch');
var axios = require('axios');
async function fetchTest(host, port, body) {
const response = {
successMessage: '',
errorMessage: ''
}
try {
const streamResponse = await fetch(`${host}:${port}`, {
method: 'post',
body: JSON.stringify(body)
})
const jsonResponse = await streamResponse.json()
response.successMessage = jsonResponse;
} catch (error) {
response.errorMessage = error;
}
return response;
}
async function axiosTest(host, port, body) {
const response = {
successMessage: '',
errorMessage: ''
}
try {
const jsonResponse = await axios({
method: 'post',
url: `${host}:${port}`,
data: body
})
response.successMessage = jsonResponse;
} catch (error) {
response.errorMessage = error;
}
return response;
}
async function test() {
console.log(await fetchTest('http://127.0.0.1', '8801', { type: 'request', cmd: 'devices' }));
console.log(await axiosTest('http://127.0.0.1', '8801', { type: 'request', cmd: 'devices' }));
}
test();
The request made with node-fetch works nicely. The request made with axios returns (IP address redacted with ...) an error:
{ successMessage: '',
errorMessage:
{ Error: connect ECONNREFUSED ...:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1161:14)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '...',
port: 80,
config:
{ adapter: [Function: httpAdapter],
transformRequest: [Object],
transformResponse: [Object],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers: [Object],
method: 'post',
url: 'http://127.0.0.1:8801',
data: '{"type":"request","cmd":"devices"}' },
request:
Writable {
_writableState: [WritableState],
writable: true,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 1,
_redirects: [],
_requestBodyLength: 39,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [ClientRequest],
_currentUrl: 'http://.../',
_isRedirect: true },
response: undefined } }
What might be the reason? Am I doing something wrong?
EDITED with more info requested in comment:
The axios request fails the same way if I comment out the node-fetch request.
The node-fetch request returns:
{
cmd: 'devices',
payload: { devices: [Array] },
type: 'response' },
}
Since I wrap the result in a response object, the console.log looks like
{
successMessage:
{
cmd: 'devices',
payload: { devices: [Array] },
type: 'response'
},
errorMessage: ''
}

sails-permissions blacklist read criteria

I have a model with a payment ID, and when I do a GET request it returns the blacklisted item
WorkOrder.create({
id: 1,
requestedDate: new Date(),
user: user[0],
product: product[0],
paid: true,
paymentID: 'abcd12'
})
When I do a simple get call to /workOrder/1
it('should not return the paymentID to the registered user', function(){
return request
.get('/workOrder/1')
.expect(200)
.then(function(res){
console.log(res.body)
return expect(res.body.paymentID).to.equal(undefined)
})
})
It returns the paymentID with the payload
{ user: 322,
product: 733,
id: 1,
requestedDate: '2016-11-06T15:04:41.174Z',
paid: true,
paymentID: 'abcd12',
createdAt: '2016-11-06T15:04:41.179Z',
updatedAt: '2016-11-06T15:04:41.179Z' }
even though in bootstrap.js I have
ok = ok.then(function(){
return PermissionService.grant({
role: 'registered',
model: 'WorkOrder',
action: 'read',
criteria: {blacklist: ['paymentID']}
})
})
and in criteria
sails> Criteria.find({}).then(function(r) {console.log(r)})
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
sails> [
{ permission: 11953,
blacklist: [ 'paymentID' ],
createdAt: '2016-11-06T15:11:52.648Z',
updatedAt: '2016-11-06T15:11:52.648Z',
id: 46 } ]
and in permissions
sails> Permission.find({id: 11953}).populate('model').populate('role').then(function(r){console.log(r)})
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
sails> [ { model:
{ name: 'WorkOrder',
identity: 'workorder',
attributes:
...
id: 2029 },
role:
{ name: 'registered',
active: true,
createdAt: '2016-11-06T15:11:51.522Z',
updatedAt: '2016-11-06T15:11:51.522Z',
id: 572 },
action: 'read',
relation: 'role',
createdAt: '2016-11-06T15:11:52.640Z',
updatedAt: '2016-11-06T15:11:52.642Z',
id: 11953 } ]
In the WorkOrder model, add this toJSON function near the end of the file (still inside the module.exports). Basically what it does is that before the model ever gets parsed into JSON, it removes the paymentID
// Remove the password when sending data to JSON
toJSON: function() {
var obj = this.toObject();
delete obj.paymentID;
return obj;
},
This link to the Sails Docs explains the concept in further detail along with more examples.

Iron router routes from db

I try to load my routes from db. My collection schema for routes is:
AsideMenu.attachSchema(
new SimpleSchema({
name: {
type: String,
denyUpdate: true
},
path: {
type: String,
denyUpdate: true
},
controller: {
type: String,
denyUpdate: true
}
})
);
I defined also a method for publish and subscribe and everything works well, i can get on client all the records on which he has access, but i cant get the router to register them.
_.map(menuRoutes, function (route) {
Router.route(route.path,
{
name: route.name,
controller: route.controller,
})
})
When I access in client console:
console.log(Router.routes) I get []
And if i print it in server console i get all routes:
I20150227-19:02:47.753(2)? { [Function]
I20150227-19:02:47.753(2)? getName: [Function],
I20150227-19:02:47.753(2)? findControllerConstructor: [Function],
I20150227-19:02:47.754(2)? createController: [Function],
I20150227-19:02:47.754(2)? setControllerParams: [Function],
I20150227-19:02:47.754(2)? dispatch: [Function],
I20150227-19:02:47.754(2)? path: [Function],
I20150227-19:02:47.754(2)? url: [Function],
I20150227-19:02:47.755(2)? params: [Function],
I20150227-19:02:47.755(2)? get: [Function],
I20150227-19:02:47.755(2)? post: [Function],
I20150227-19:02:47.755(2)? put: [Function],
I20150227-19:02:47.755(2)? delete: [Function],
I20150227-19:02:47.756(2)? options:
I20150227-19:02:47.756(2)? { name: 'calendar.index',
I20150227-19:02:47.756(2)? controller: 'CalendarController',
I20150227-19:02:47.756(2)? data: [Function],
I20150227-19:02:47.756(2)? mount: false },
I20150227-19:02:47.757(2)? _actionStack: { _stack: [], length: 0 },
I20150227-19:02:47.757(2)? _beforeStack: { _stack: [], length: 0 },
I20150227-19:02:47.757(2)? _afterStack: { _stack: [], length: 0 },
I20150227-19:02:47.757(2)? _methods: {},
I20150227-19:02:47.758(2)? _path: '/calendar',
I20150227-19:02:47.758(2)? handler:
I20150227-19:02:47.758(2)? { options: [Object],
I20150227-19:02:47.758(2)? mount: false,
I20150227-19:02:47.758(2)? method: false,
I20150227-19:02:47.759(2)? where: 'client',
I20150227-19:02:47.759(2)? name: 'calendar.index',
I20150227-19:02:47.759(2)? path: '/calendar',
I20150227-19:02:47.759(2)? compiledUrl: [Object],
I20150227-19:02:47.759(2)? handle: [Circular],
I20150227-19:02:47.917(2)? route: [Circular] },
I want to know if this is possible because i couldnt find any example with this aproach.
Yes, this should be possible. I have a similar setup working just fine, the only difference being that I create the routes from a static array, not a db query. But that should make a difference.
This works for me, when executed during load:
_.each(routes, function(foo, route) {
Router.map(function () {
this.route(route, {
path: route,
action: function() { ... }
});
});
});
Where/when are you executing the _.map code you showed?
Iron router runs a reactive computation, but at the time your subscription to your route definitions collection is not ready. So if you put that block in your ready callback which is:
Meteor.subscribe('router-data-publication', function() {
/* construct your routes here*/
});
or, you can do something safer, but essentially the same, using a handle within a Tracker and checking .ready() on the handler.