Sailsjs: can't create dummy object on bootstrap with Date attribute - javascript

I'm able to create to create a dummy user object at bootstrap before adding a "Date" attribute. In bootstrap.js I have:
module.exports.bootstrap = function(cb) {
var dummyData = [
{
"firstName":"Jane",
"lastName":"Doe",
"dateofbirth": 1279703658 //timestamp
}
]
User.count().exec(function(err, count){
if(err){
return cb(err);
}
if(count == 0){
User.create(dummyData).exec(function(){
cb();
});
}
});
};
User.js is simple and looks like this:
module.exports = {
attributes: {
firstName : {
type : 'string',
required : true
},
lastName : {
type : 'string',
required : true
},
dateofbirth : {
type : 'date'
}
}
};
when I try creating the same object in browser (sails nice CRUD functionality) I get an error about the date:
{
"error": "E_VALIDATION",
"status": 400,
"summary": "1 attribute is invalid",
"model": "User",
"invalidAttributes": {
"dateofbirth": [
{
"rule": "date",
"message": "`undefined` should be a date (instead of \"123454345\", which is a string)"
}
]
}
}
So question is how can I create such object with date attribute?

date (or the equivalent dateTime) accepts e.g. an ISO date string. So, your example could look like:
var dummyData = [
{
"firstName":"Jane",
"lastName":"Doe",
// "1970-01-15T19:28:23.658Z"
"dateofbirth": new Date(1279703658).toISOString()
}
]

Related

mongo using mongoose in node want to use or and in query

I have a situation where I have to check name of the company and code of the company and if both match with existing than it should say exists, or if one of them is matched in existing db then also it should be saying it exists.
How would I use in mongo?
So if the data receive isDeleted true than I also want to add in if section that checks if not adding than goes for checking id and update, than I also want to pass isDelete, so that if any data received which is previously deleted so that it can set to false again.
how would I handle this delete scenario?
{
"userId":"tt838984984s",
"company":{
"addressee" : {
"addressee" : "Ms.1",
"title_name" : "",
"salutation" : "Drks:",
"comments" : "",
"email" : "opus7ent#example.com",
"phone" : "123456666",
"fax" : "",
"extention_group" : "",
"ext" : ""
},
"abbreviation" : "",
"care_of" : "",
"address_1" : "HELLO2",
"address_2" : "",
"address_3" : "",
"state" : "CA",
"zip" : "90024",
"is_deleted" : true,
"company_code" : "ABACAB",
"parent_company" : null,
"name" : "Abacab",
"createdBy" : "Data lolz",
"modifiedBy" : "Data",
"createdDate" : "2019-08-22T19:10:50.000+0000",
"modifiedDate" : "2019-08-22T19:10:50.000+0000",
"company_id_legacy" :1246,
"__v" : 0,
"is_registered_for" : false,
},
}
is_deleted == false
if(!isAdd) {
filter["_id"] ={ "$ne" : id};
}
let filter = {
name: { $regex: new RegExp(`^${company.name}$`, 'i') },
company_code: { $regex: new RegExp(`^${company.company_code}$`, 'i') }
}
cModel.find(filter, function (err, docs) {
if (docs.length) {
result.error = "Name already exists: " + company.name;
console.log("Name already exists", null);
let resp = api_respose.getSuccessResponse(process.env.WEB_URI, result.error);
resolve(resp);
}
else{
///saving here
}
Now suppose I pass that JSON, and if there's is_deleted = false (this is Json while adding new entry in db)
And now if there's some old entry with name or company_code exists in db with is_delete =true then it throws error that name already exits
Now my question is how to resolve this scenario? Like I want to overwrite that file with new entry or is there any other way of doing this?
You can use $or operator
let filter = {
"$or":[
name: { $regex: new RegExp(`^${company.name}$`, 'i') },
company_code: { $regex: new RegExp(`^${company.company_code}$`, 'i')
]
}
}
cModel.find(filter, function (err, docs) {
if (docs.length) {
result.error = "Name already exists: " + company.name;
console.log("Name already exists", null);
let resp = api_respose.getSuccessResponse(process.env.WEB_URI, result.error);
resolve(resp);
}
else{
///saving here
}
refer https://docs.mongodb.com/manual/reference/operator/query/or/ for more info
If I have correctly understood, you need using $or inside of $and function in Mongodb or mongoose, both of them supports these two functions. For example (in mongoose):
cModel.find(
{
$and: [
{
$or: [
{ name: { $regex: new RegExp(`^${company.name}$`, 'i') } },
{ company_code: { $regex: new RegExp(`^${company.company_code}$`, 'i') } }
]
},
{
is_delete: true
}
]
}, function (err, docs) {
if(docs){
// throw error!
} if (!docs) {
// enter your new doc here with cModel.create(yourDoc, function(error, data){});
}
}
);
complete documentation for this function is here:
https://docs.mongodb.com/manual/reference/operator/query/and/

mongoDB: Can't add an field to an array object

This is how my db document looks like:
{
"_id" : "aN2jGuR2rSzDx87LB",
"content" : {
"en" : [
{
"content" : "Item 1",
"timestamp" : 1518811796
}
]
}
}
Now I need to add another field in the first object of the content.en array.
The document itself gets selected by an ID.
The result should be:
{
"_id" : "aN2jGuR2rSzDx87LB",
"content" : {
"en" : [
{
"content" : "Item 1",
"timestamp" : 1518811796,
"user" : {
"id" : 'userId'
}
}
]
}
}
I tried to do it like this, but nothing is happening. I don't even get an error message.
Content.update(
{ _id: id },
{
$addToSet: {
'content.en.0.user': {
id: 'userId',
}
}
}
)
Also I would like to use an variable for the language. How do I do that? Something like 'content.' + language + '.0.user'...
$addToSet is useful when you want to add someting to an array. In your case you want to modify first element of your array (at index 0) so you should simply use $set (which is field update operator):
Content.update(
{ _id: "aN2jGuR2rSzDx87LB" },
{
$set: {
"content.en.0.user": {
id: "userId",
}
}
}
)

In-/upserting a nested document in MongoDB

I'm trying to upsert a nested document (activities) in a structure similar to
{
"_id" : "123",
"modules" : {
"x" : {
},
"y" : {
"activities" : {
"preview": {
"createdAt": "2014-10-13 15:21:22.113",
"data": {}
}
}
},
"z" : {
"activities" : {
"render": {
"createdAt": "2014-10-15 04:22:25.171",
"data": {}
},
"render": {
"createdAt": "2014-10-14 02:42:24.132",
"data": {}
}
}
}
}
}
I then try
selector = { "_id": id, "modules": module, "activities" }
activity = { "preview": { "data": data }}
Meteor.users.upsert(selector, { $set: activity, $setOnInsert: { "createdAt: new Date()" }})
Which yields
MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: meteor.users.$_id_ dup key: { : "123" }
_id is a unique index key. There are additional fields/documents on the _id 'level' of each user and on the activities 'level' of each module, but none concerning the upsert. Each module is unique. The activities document doesn't exist before the first record is inserted.
With that, I hope someone gets the gist of what I'm trying to accomplish and can help me in the right direction.
Upsert is for insert or update(if exist) a new document. It does not apply for a sub-document.
You should just update your document:
selector = { "_id": id, "modules": module, preview : null }
activity = { "preview": { "data": data , "createdAt" : new Date() }}
Meteor.users.update(selector, { $set: 'activity' : activity }})

Editing an inner array that is only present some docs

I have a JSON entry within mongo:
{
_id: "fe50fdee-4ea3-4824-94af-f369633c0c7a",
_class: "com.tracking.daoservice.model.TrackingData",
modified: ISODate("2014-09-10T23:38:48.407Z"),
eventtype: "William-Test",
eventdata: {
QueryDate: "01-APR-2014",
SearchQuery: {
keyword: "Java",
location: "Santa Clara, CA",
Facet: "skill~java~perl|workAuth~USC",
SearchAgentId: "4299"
},
Viewed: [
{
ViewedID: "8992ade400a",
Dockey: "3323aba3233",
PID: "32399a",
actionsTaken: "email|direct message|report seeker",
viewDate: "01-APR-2014",
MessageSent: "true",
Message: [
{
MessageID: "123aca323",
Delivered: "True",
Opened: "True",
ClickThroughRate: "NotBad",
MessageDate: "02-APR-2014",
Response: [
{
ResponseId: "a323a9da",
ResponseDate: "23-APR-2014"
}
]
}
]
}
]
},
eventsource: "API-Dev Test - JMachine",
sourceip: "myIp",
entityid: "TmoneyBunnyWunny",
groupid: "Dice",
datecreated: ISODate("2014-09-10T23:38:48.405Z")
}
I have a script to change the inner date attributes,
db.TRACKING_DATA.find().forEach(function(doc) {
db.TRACKING_DATA.update({
"_id": doc._id,
"eventdata.Viewed.viewDate":doc.eventdata.Viewed[0].viewDate
}, {
"$set": { "eventdata.Viewed.$.Message.0.MessageDate": new Date( doc.eventdata.Viewed[0].Message[0].MessageDate) }
}
)
});
The problem is not all of the docs contain the inner object:
Message: [
{
MessageID: "123aca323",
Delivered: "True",
Opened: "True",
ClickThroughRate: "NotBad",
MessageDate: "02-APR-2014",
Response: [
{
ResponseId: "a323a9da",
ResponseDate: "23-APR-2014"
}
]
}
]
So when I run it, it returns:
TypeError: Cannot read property '0' of undefined
I need a way to basically say:
if(Message exists change these entries within it)
I have tried a number of variations on:
db.TRACKING_DATA.find().forEach(function(doc) {
db.TRACKING_DATA.update(
{
"_id": doc._id,
"eventdata.Viewed.viewDate":doc.eventdata.Viewed[0].viewDate, doc.eventdata.Viewed[0].Message[0]: {$exists}
},
{
"$set": {"eventdata.Viewed.$.Message.0.MessageDate": new Date( doc.eventdata.Viewed[0].Message[0].MessageDate) }
}
)
});
but unable to find a viable solution.
Cheers,
Add some judgement will help.
db.TRACKING_DATA.find().forEach(
function(doc) {
var Viewed = doc.eventdata.Viewed;
if (Viewed instanceof Array && Viewed[0]) {
var Message = Viewed[0].Message;
if (Message instanceof Array && Message[0]) {
db.TRACKING_DATA.update({
"_id" : doc._id,
"eventdata.Viewed.viewDate" : Viewed[0].viewDate
}, {
"$set" : {
"eventdata.Viewed.$.Message.0.MessageDate" : new Date(Message[0].MessageDate)
}
});
}
}
});
I guess you want to change field type from String to Date on every MessageDate of Message. If true you need to change these codes. Above only change the first element according to your original codes.

How to verify an observable object have all the required members?

Basically I want to validate my observable before apply the bindings, so that I will never get that something something is not defined error.
Say I do have a javascript class that defines all that I need, and I want to validate an observable created from ajax against it.
Is there a generic way to do it?
Edit:
http://jsfiddle.net/rgneko/GuR8v/
Currently the demo will throw error because one of the items has no id property. I want to verify whether all items are valid.
$(document).ready(function () {
function ModelToTestAgainst(id, name, type, items) {
this.id = id;
this.name = name;
this.type = type;
this.items = items;
}
var data = {
items: [{
id: 1,
name: 'name1',
type: 'folder',
items: []
}, {
id: 2,
name: 'name2',
type: 'file',
items: []
}, {
name: 'name2',
type: 'file',
items: []
}]
};
var someRandomObservaleIGotFromWherever = ko.mapping.fromJS(data);
// I want to Validate(someRandomObservaleIGotFromWherever) before apply bindings
ko.applyBindings(someRandomObservaleIGotFromWherever);
});
There is a standard JSON Schema, defined in http://json-schema.org/.
An schema can be as simple as:
var schema = {"type" : "object"};
which requires the value to be an object. Or much more complex, like this example from json-schema.org:
{
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
which requires several properties to exists, defines their types, and even a minimun value for one of them.
Then you need a library that allows to validate the JS objects with this kind of schema. In the same site, you can find a list of libraries for validating (and parsing, creating documentation...). Note that not all libraries are updated, and not all of them support the latest JSON schema version.
For example, using JSV, you can make a validation simply like this:
var report = env.validate(json, schema);
Why don't you map/wrap it into a view model that you know has all the properties that you need?
function ViewModel(model) {
this.x = ko.observable(model.x || 0);
this.y = ko.observable(model.y || 0);
}
var original = { x: 27 }; // Use your ajax object here.
var viewModel = new ViewModel(original);
What about using JSON Schema validation.
I have used library from Tiny Validator to enable validation. Validation is easy to add as an observable extension
$(document).ready(function () {
// Attach a validationSchema method to all observable types
ko.subscribable.fn["validateSchema"] = function(schema){
// Convert the observable back to an object literal to test.
var source = ko.mapping.toJS(this());
return tv4.validate(source, schema);
};
// Define schema for ModelToTestAgainst
var modelSchema = {
"$schema": "http://tempuri.org/ModelToTestAgainst",
"title": "ModelToTestAgainst Set",
"type": "array",
"items": {
"title": "ModelToTestAgainst",
"type": "object",
"properties" : {
"id" : {
"type": "number",
"minimum" : 1
},
"name" : { "type": "string" },
"type" : { "type": "string" },
"items" : { "type" : "array" }
},
"required": ["id", "name", "type", "items"]
}
};
function ModelToTestAgainst(id, name, type, items) {
this.id = id;
this.name = name;
this.type = type;
this.items = items;
}
var data = {
items: [{
id: 1,
name: 'name1',
type: 'folder',
items: []
}, {
id: 2,
name: 'name2',
type: 'file',
items: []
}, {
name: 'name2',
type: 'file',
items: []
}]
};
var obs = ko.mapping.fromJS(data));
var isValid = obs.items.validateSchema(modelSchema);
if( isValid ) {
ko.applyBindings(obs);
}
});

Categories

Resources