Sequelize mysql query where attribute is null - mysql

I have an address and I want to see if it's in the db already, if not, create a new one. I know I can use findOrCreate() here, but let's make it easy and just check why I can't even find the existing address.
var address = {
name: req.body.name,
address1: req.body.address1,
address2: req.body.address2,
zip: req.body.zip,
city: req.body.city,
country: req.body.country,
user_id: req.body.user_id
};
Address.find({where: address}).then(function(result){
console.log(result);
}).catch(function(err){
console.error(err);
});
The generated query asks for ... AND user_id = NULLwhich is wrong. It should ask ... AND user_id IS NULL. How can I let sequelize do it right for me? Thanks.

You should just use the JavaScript null primitive.
var address = {
name: req.body.name,
address1: req.body.address1,
address2: req.body.address2,
zip: req.body.zip,
city: req.body.city,
country: req.body.country,
user_id: req.body.user_id || null
};
This will generate the query
... user_id IS NULL
Additional information
model.findAll( { where: { some_column : undefined } } );
will generate
... WHERE `some_column` = NULL

Related

Yeoman repeat prompt based on user input

For example, I want to ask the user for the type of bread:
{
type: 'list',
name: 'breadType',
message: `What type of bread do you want?`,
choices: response => {
const breadOptions = [
{
value: 'wheat',
name: 'Wheat Bread'
},
{
value: 'white',
name: 'White Bread'
}
];
return breadOptions;
},
default: 0
}
Then I'll ask for toppings based on the number of toppings they want:
{
when: response => response.breadType,
type: 'input',
name: 'numberOfToppings',
message: 'Please enter how many toppings you want: '
}
How would I prompt however many times user input for number of toppings?:
{
when: response => response.numberOfToppings,
type: 'input',
name: 'toppingChoices',
message: 'Please provide your topping(s): '
}
SAMPLE INPUT:
? Please enter how many toppings you want: 4
? Please provide your topping(s):cheese
? Please provide your topping(s):onions
? Please provide your topping(s):pickles
? Please provide your topping(s):tomatoes
I'm unfamiliar with yeoman syntax, please help.
I made a simple generator that solve your problem:
const Generator = require('yeoman-generator');
let toppings = [];
module.exports = class extends Generator {
async prompting() {
const answers = await this.prompt([
{
type: 'input',
name: 'numberOfToppings',
message: 'Please enter how many toppings you want: ',
}
]);
var length = answers.numberOfToppings;
for(var i = 0; i < length; i++) {
const answers2 = await this.prompt([
{
type: 'input',
name: 'toppings',
message: 'Please provide your topping(s):',
}
]);
toppings.push(answers2.toppings);
}
console.log('Array: ' + toppings);
}
};

if the json is duplicate, return the first element

I'm not sure if there is already a function for this, what I need is the following
a json in reactjs, and I need this to search if the cities are repeated and return only one result,
example if I have 5 berlin, only the first berlin returns
If I have 5 california, the first california returns
[
{id:1, city: "berlin"},
{id:2, city: "berlin"},
{id:3, city: "berlin"},
{id:5, city: "california"},
{id:6, city: "california"},
{id:7, city: "california"}
]
thanks for your help
Filter the results using a Set to check for duplicates:
const arr = [{"id":1,"city":"berlin"},{"id":2,"city":"berlin"},{"id":3,"city":"berlin"},{"id":5,"city":"california"},{"id":6,"city":"california"},{"id":7,"city":"california"}];
const result = arr.filter(function({ city }) {
return this.has(city) ? false : this.add(city);
}, new Set);
console.log(result);
Or reduce the array to a Map by country, and spread back to array:
const arr = [{"id":1,"city":"berlin"},{"id":2,"city":"berlin"},{"id":3,"city":"berlin"},{"id":5,"city":"california"},{"id":6,"city":"california"},{"id":7,"city":"california"}];
const result = [...arr.reduce((m, o) => m.has(o.city) ? m : m.set(o.city, o), new Map).values()];
console.log(result);

Mongoose find-query: Sort JSON-Array by Date

I tried this mongoose-query and have no idea why this sort doesn't work (found syntax on stackoverflow so no Idea what I did wrong again).
Tried to replace exec with find, doesnt work either.
model.find({'id':req.params.id}).sort({date:-1}).limit(10).exec(function(err, jsonarray){...};
My schema and jsondata is like that:
var messageSchema = new Schema({
id: Number,
name: Schema.Types.Mixed,
type: Schema.Types.Mixed,
message:
{
messagetype: String,
timestamp: Number,
messagestatus: String
}
}, {collection: 'test'});
Otherwise could sort it by message.timestamp but I have no idea how..
Thanks in advance.
Even tried it like that.. I'm stuck.
json.sort(function(a, b) {
return parseFloat(a.message.timestamp) - parseFloat(b.message.timestamp);
});
Update: Data looks like that:
[ { id: 215456740,
name: 'Max',
type: 'freezer',
_id: 57513933c25d06630a3ef887,
__v: 0,
message:
{ messagetype: 'Standard message',
timestamp: 1464940851375,
messagestatus: 'red'
}
},
{ id: 215456740,
name: 'Tobi',
type: 'center',
_id: 5751393bc25d06630a3ef888,
__v: 0,
message:
{ messagetype: 'Standard message',
timestamp: 1464940859265,
messagestatus: 'white'
}
}]
Yes, it's intentional, multiple messages for one Id.
This is the output
The query is sorting on a non-existent property date:
.sort({ date : -1 })
Instead, try this:
.sort({ 'message.timestamp' : -1 })
.sort({_id: -1})
Used autocreated _id as it has an embedded Date. Worked afterwards.

Preprocessing Mongoose documents right after querying

Abstract
Hi, I have two models City and Country:
var Country = new Schema({
name: String,
population: String
});
var City = new Schema({
name: String,
timeZone: { type: Number, min: -12, max: 12 },
summerTime: Boolean,
country: { type: Schema.ObjectId, ref: 'Country'}
});
When I'm querying data from mongo using the following way:
function (request, response) {
var CityModel = mongoose.model('City', City);
CityModel.find().lean().populate('country').exec(function(err, docs){
response.send(JSON.stringify(docs));
});
}
But on client when I parse JSON, I get multiple instances of the same country:
var cities = $.get('/cities').then(function(citiesJson){
var cities = JSON.parse(citiesJson);
var washingtonIndex = ...;
var californiaIndex = ...;
var washington = cities[washingtonIndex];
var california = cities[californiaIndex];
washington.country.population = "300 000 000";
california.country.population = "500 000 000";
console.log([california.country.population, california.country.population]);
});
Resulting with two values ["300 000 000", "500 000 000"] in the console.
The problem
To prevent this kind of behaviour and preserve object references I'm doing JSON.decycle before object serialization:
...
response.send(JSON.stringify(JSON.decycle(docs)));
...
It works better than it should be. As a result I get the following JSON on the client:
// City:
{
name: "Bost",
deleted: "0",
country: {
$ref: "$[0]["city"]["country"]"
},
lastModified: "2013-08-06T23:44:11.000Z",
_id: {
_bsontype: "ObjectID",
id: "Rm1'"
},
approved: "1"
}
Notice the _id field which is getting serialized by reference so I don't get the actual ObjectId's string representation on the client, instead I'm getting some internal mongo representation of the id which is not usable on the client.
The question
1) Is there a way to setup per model or per schema preprocessing for all queried documents so that I convert ObjectId's into string
2) Probably there is some other more efficient way of dealing with this problem?
Thanks

ScriptDB auto numbering

I have a database like this one:
var db = ScriptDb.getMyDb();
var ob = {
type: "employee",
employee_id: 1,
name: {
first: "Fatima",
initial: "S",
last: "Pauli"
},
address: {
street: "4076 Washington Avenue",
city: "Jackson", state: "MS", zip: "39201"
},
department_id: 52
};
var stored = db.save(ob);
Now I want the employee_id to have auto-increment without looping trough the entire existing database.
What is the best way to do this?
A solution is to store a current max value of employee_id in a separate ScriptDB object and use the LockService to provide atomicity, as shown here, during reading and incrementing operations.