I am trying to not make my code redundant and I would like to know, if in a .updateOne method, when Im passing data to change, if its possible to implement if statement to choose from the data. Here is a situation.
I have my db model:
const depositarySchema = new Schema({
euid: {
type: String,
required: true
},
euid2: {
type: String
},
count: {
type: Number,
required: true
},
euroPallets: {
type: Number,
},
biggerPallets: {
type: Number,
},
otherPallets: {
type: Number,
},
depositary: {
type: Number,
required: true
},
title: {
type: String
}
});
Then I have a variable: var = 1 for euroPallets, 2 for biggerPallets and 3 for otherPallets. I would like to implement something like this:
Depositary.updateOne(
{
euid: euid,
},
{
count: dep.count - palletCounter,
if(var === 1){
euroPallets: count}
elseif(var===2){
biggerPallets: count}
else{
otherPallets: count}
},
where count is just a number. I hope its understandable what im trying to achieve, sorry for a wrong syntax.
Wernfried Domscheit beat me to it, but I will post my answer anyways.
const palletTypes = ['otherPallets', 'euroPallets', 'biggerPallets'];
var count = ep.count - palletCounter;
var palletType = palletTypes[count] || palletTypes[0];
var pallets = {'count': count};
pallets[palletType] = count;
Depositary.updateOne(
{euid: euid},
pallets
)
I would honestly just make a helper method so you can just send in parameters and it will turn everything to the correct objects.
updatePallets(euid, ep.count, palletCounter)
Maybe this one:
let upd = {
euid: euid,
count: dep.count - palletCounter
};
if (var === 1) {
upd['euroPallets'] = count;
}
else if (var === 2) {
upd['biggerPallets'] = count;
}
else {
upd['otherPallets'] = count;
}
Depositary.updateOne(upd)
EDIT:
For .updateOne() method to actually work like I want to, you need to separate the euid parameter. The correct solution is this:
let upd = {
count: dep.count - palletCounter
};
if (var === 1) {
upd['euroPallets'] = count;
}
else if (var === 2) {
upd['biggerPallets'] = count;
}
else {
upd['otherPallets'] = count;
}
Depositary.updateOne(
{
euid: euid,
},
upd,
)
Related
I have a model where I store some "views", but in some part of my code, I only want to get the ones which kind value is equal to home.
I need it to be done by Ajax.
The code below already gets all the elements of the database, but I just need those with the kind attribute equal to home:
'onTabShow':function (tab, navigation, index) {
console.log(index);
if (index == 1){
$.ajax({
type: 'GET',
url: '/userpanel/webapi/viewlist',
dataFilter:(kind,home),//this doesnt work, there has to be a way to properly do it
}).done(function(response) {
console.log(response);
})
}
}
});
this is the model code
var TIPOS_MEDIA = 'video serie picture sound live home'.split(' ');
const View = new Schema({
viewname: String,
component: String,
componenturl: String,
screenshot: String,
price: Number,
kind: { type: String, enum: TIPOS_MEDIA, default: 'video' },
options: [{ type: Schema.Types.ObjectId, ref: 'Option' }],
platform: { type: Schema.Types.ObjectId, ref: 'Platform' },
});
ViewModel = mongoose.model('View', View);
module.exports = ViewMode
in case of being needed this is the webapi code
router.get('/userpanel/webapi/viewlist', function(req, res) {
View.find({})
.populate("options",'optionname')
.populate("platform")
.exec(function(err, views) {
if (err) {
res.send(err);
} else {
var _views = [];
for (var i = views.length - 1; i >= 0; i--) {
var view = {
_id:views[i]._id,
viewname:views[i].viewname,
component:views[i].component,
componenturl:views[i].componenturl,
screenshot:views[i].screenshot,
price:views[i].price,
kind:views[i].kind,
platform:views[i].platform.platformname,
};
var optionnames = "";
for (var i2 = views[i].options.length - 1; i2 >= 0; i2--) {
optionnames = optionnames + views[i].options[i2].optionname + ","
}
view.optionnames = optionnames;
_views.push(view);
}
res.json({
data:_views
});
}
})
});
How to update a record inside model's method like 'node orm-2' In 'Sequelize'
In orm-2, Just use this.save()
var users = db.define('users',
{
id : { type: 'serial', key: true },
username : { type: 'text', size: 25, unique: true, required: true },
balance : { type: 'integer', defaultValue: 0 },
}, {
timestamp: true,
methods: {
addBalance: function (howMany) {
howMany = Math.abs(howMany);
this.balance += howMany;
this.save(function (err) {
console.log("added money to "+this.username+" : "+howMany);
});
}
}
});
But in Sequelize, I don't know yet
var wallet = sequelize.define('wallet', {
balance : { type: Sequelize.INTEGER, defaultValue: 0, validate: { min: 0 } }
}, {
timestamps: true,
classMethods: {
addBalance: function (howMany) {
howMany = Math.abs(howMany);
this.balance += howMany;
//UPDATE Or SAVE HERE...
}
}
});
Is it have simple command or prefer another methods?
You should place the addBalance method inside instanceMethods, not in classMethods, because you want to operate on a single instance of specified model
instanceMethods: {
addBalance: function(howMany) {
howMany = Math.abs(howMany);
return this.set('balance', this.get('balance') + howMany).save();
}
}
This method would return Promise resolving to current instance of model.
EDIT
Even better solution would be to use instance.increment method
addBalance: function(howMany) {
howMany = Math.abs(howMany);
return this.increment('balance', { by: howMany });
}
It would return the same as the option above.
I am not very good with my javascript but recently needed to work with a library to output an aggregated table. Was using fin-hypergrid.
There was a part where I need to insert a sum function (rollups.sum(11) in this example)to an object so that it can compute an aggregated value in a table like so:
aggregates = {Value: rollups.sum(11)}
I would like to change this value to return 2 decimal places and tried:
rollups.sum(11).toFixed(2)
However, it gives the error : "rollups.sum(...).toFixed is not a function"
If I try something like:
parseFloat(rollups.sum(11)).toFixed(2)
it throws the error: "can't assign to properties of (new String("NaN")): not an object"
so it has to be a function object.
May I know if there is a way to alter the function rollups.sum(11) to return a function object with 2 decimal places?
(side info: rollups.sum(11) comes from a module which gives:
sum: function(columnIndex) {
return sum.bind(this, columnIndex);
}
)
Sorry I could not post sample output here due to data confidentiality issues.
However, here is the code from the example I follow. I basically need to change rollups.whatever to give decimal places. The "11" in sum(11) here refers to a "column index".
window.onload = function() {
var Hypergrid = fin.Hypergrid;
var drillDown = Hypergrid.drillDown;
var TreeView = Hypergrid.TreeView;
var GroupView = Hypergrid.GroupView;
var AggView = Hypergrid.AggregationsView;
// List of properties to show as checkboxes in this demo's "dashboard"
var toggleProps = [{
label: 'Grouping',
ctrls: [
{ name: 'treeview', checked: false, setter: toggleTreeview },
{ name: 'aggregates', checked: false, setter: toggleAggregates },
{ name: 'grouping', checked: false, setter: toggleGrouping}
]
}
];
function derivedPeopleSchema(columns) {
// create a hierarchical schema organized by alias
var factory = new Hypergrid.ColumnSchemaFactory(columns);
factory.organize(/^(one|two|three|four|five|six|seven|eight)/i, { key: 'alias' });
var columnSchema = factory.lookup('last_name');
if (columnSchema) {
columnSchema.defaultOp = 'IN';
}
//factory.lookup('birthState').opMenu = ['>', '<'];
return factory.schema;
}
var customSchema = [
{ name: 'last_name', type: 'number', opMenu: ['=', '<', '>'], opMustBeInMenu: true },
{ name: 'total_number_of_pets_owned', type: 'number' },
{ name: 'height', type: 'number' },
'birthDate',
'birthState',
'employed',
{ name: 'income', type: 'number' },
{ name: 'travel', type: 'number' }
];
var peopleSchema = customSchema; // or try setting to derivedPeopleSchema
var gridOptions = {
data: people1,
schema: peopleSchema,
margin: { bottom: '17px' }
},
grid = window.g = new Hypergrid('div#json-example', gridOptions),
behavior = window.b = grid.behavior,
dataModel = window.m = behavior.dataModel,
idx = behavior.columnEnum;
console.log('Fields:'); console.dir(behavior.dataModel.getFields());
console.log('Headers:'); console.dir(behavior.dataModel.getHeaders());
console.log('Indexes:'); console.dir(idx);
var treeView, dataset;
function setData(data, options) {
options = options || {};
if (data === people1 || data === people2) {
options.schema = peopleSchema;
}
dataset = data;
behavior.setData(data, options);
idx = behavior.columnEnum;
}
// Preset a default dialog options object. Used by call to toggleDialog('ColumnPicker') from features/ColumnPicker.js and by toggleDialog() defined herein.
grid.setDialogOptions({
//container: document.getElementById('dialog-container'),
settings: false
});
// add a column filter subexpression containing a single condition purely for demo purposes
if (false) { // eslint-disable-line no-constant-condition
grid.getGlobalFilter().columnFilters.add({
children: [{
column: 'total_number_of_pets_owned',
operator: '=',
operand: '3'
}],
type: 'columnFilter'
});
}
window.vent = false;
//functions for showing the grouping/rollup capabilities
var rollups = window.fin.Hypergrid.analytics.util.aggregations,
aggregates = {
totalPets: rollups.sum(2),
averagePets: rollups.avg(2),
maxPets: rollups.max(2),
minPets: rollups.min(2),
firstPet: rollups.first(2),
lastPet: rollups.last(2),
stdDevPets: rollups.stddev(2)
},
groups = [idx.BIRTH_STATE, idx.LAST_NAME, idx.FIRST_NAME];
var aggView, aggViewOn = false, doAggregates = false;
function toggleAggregates() {
if (!aggView){
aggView = new AggView(grid, {});
aggView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked) {
grid.setAggregateGroups(aggregates, groups);
aggViewOn = true;
} else {
grid.setAggregateGroups([], []);
aggViewOn = false;
}
}
function toggleTreeview() {
if (this.checked) {
treeView = new TreeView(grid, { treeColumn: 'State' });
treeView.setPipeline({ includeSorter: true, includeFilter: true });
treeView.setRelation(true, true);
} else {
treeView.setRelation(false);
treeView = undefined;
delete dataModel.pipeline; // restore original (shared) pipeline
behavior.setData(); // reset with original pipeline
}
}
var groupView, groupViewOn = false;
function toggleGrouping(){
if (!groupView){
groupView = new GroupView(grid, {});
groupView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked){
grid.setGroups(groups);
groupViewOn = true;
} else {
grid.setGroups([]);
groupViewOn = false;
}
}
you may try:
(rollups.sum(11)).toFixed(2)
enclosing number in parentheses seems to make browser bypass the limit that identifier cannot start immediately after numeric literal
edited #2:
//all formatting and rendering per cell can be overridden in here
dataModel.getCell = function(config, rendererName) {
if(aggViewOn)
{
if(config.columnName == "total_pets")
{
if(typeof(config.value) == 'number')
{
config.value = config.value.toFixed(2);
}
else if(config.value && config.value.length == 3 && typeof(config.value[1]) == 'number')
{
config.value = config.value[1].toFixed(2);
}
}
}
return grid.cellRenderers.get(rendererName);
};
I have a list of models I want to search through and pull the url for the correct one. I won't always have the full key, and never the full value, but will always have at least a unique part of it.
Right now the code is just in test mode, with a set number that matches a key, print a success or failure.
The console keeps telling me that models[i].indexOf isn't a function. I know it's an object, but when I do a toString on it, I get "object Object". What am I not understanding?
I'm happy with a solution that is either vanilla JavaScript or uses jQuery.
The code:
if ($('.mobile_tutorial').length) {
var device = /*$device.model*/ "NTZEZ717VLU", model_code = device.substr(2).substr(0,device.length-3);
$.ajax({
url: "/scripts/phone_models.json",
type: 'get',
dataType: 'json',
success: function (data) {
var models = data.Manufacturer;
for (var i = models.length - 1; i >= 0; i--) {
if (models[i].indexOf(model_code) > -1) {
console.log(models[i])
} else {
console.log('no match')
}
}
}
});
}
The JSON (partial):
{
"Manufacturer": [{
"ZEZ955L": "http://x.com/mobile/home.seam?custId=ZEZ955L"
}, {
"ZEZ990G": "http://x.com/mobile/home.seam?custId=ZEZ990G"
}, {
"ZEZ828TL": "http://x.com/mobile/home.seam?custId=ZEZ828TL"
}, {
"ZEZ716BL": "http://x.com/mobile/home.seam?custId=ZEZ716BL"
}, {
"ZEZ717VL": "http://x.com/mobile/home.seam?custId=ZEZ717VL"
}, {
"ZEZ962BL": "http://x.com/mobile/home.seam?custId=ZEZ962BL"
}, {
"ZEZ963VL": "http://x.com/mobile/home.seam?custId=ZEZ963VL"
}]
}
models[i] is not a string so you are getting error. If you want to check key then use .each() function on models[i]. In that each loop compare the key using indexOf function.
if ($('.mobile_tutorial').length) {
var device = /*$device.model*/ "NTZEZ717VLU", model_code = device.substr(2).substr(0,device.length-3);
$.ajax({
url: "/scripts/phone_models.json",
type: 'get',
dataType: 'json',
success: function (data) {
var models = data.Manufacturer;
for (var i = models.length - 1; i >= 0; i--) {
$.each(models[i], function( key, value ) {
if (key.indexOf(model_code) > -1) {
console.log(models[i])
} else {
console.log('no match')
}
}
}});
});
}
You would need to grab the value of the key changing models[i].indexOf(model_code) to Object.keys(models[i])[0].indexOf(partial_model_code). Here's it in action:
var partial_model_code = '3VL'
function ajax(data) {
var models = data.Manufacturer;
for (var i = models.length - 1; i >= 0; i--) {
// grab the keys in the object
// since there will only be one object grab the first one
// check if the key partially matches
if (Object.keys(models[i])[0].indexOf(partial_model_code) > -1) {
console.log(models[i])
} else {
console.log('no match')
}
}
}
var data = JSON.parse(`{
"Manufacturer": [{
"ZEZ955L": "http://x.com/mobile/home.seam?custId=ZEZ955L"
}, {
"ZEZ990G": "http://x.com/mobile/home.seam?custId=ZEZ990G"
}, {
"ZEZ828TL": "http://x.com/mobile/home.seam?custId=ZEZ828TL"
}, {
"ZEZ716BL": "http://x.com/mobile/home.seam?custId=ZEZ716BL"
}, {
"ZEZ717VL": "http://x.com/mobile/home.seam?custId=ZEZ717VL"
}, {
"ZEZ962BL": "http://x.com/mobile/home.seam?custId=ZEZ962BL"
}, {
"ZEZ963VL": "http://x.com/mobile/home.seam?custId=ZEZ963VL"
}]
}`)
ajax(data)
I hope that helps!
I have an Angular application that collects values of items for an invoice, I want to make sure only unique items are being added to this collection but am having no luck.
I am pushing 3 pieces of information to this collection: id, price, and type. I want to make sure there is nothing in the collection currently matching those 3 points.
// My container
$scope.invoice = {
items: [{
}]
}
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
if ($scope.invoice.items.indexOf(item.id) != $scope.item.id)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
// Trying to avoid collections like this
invoice: {
items:
[ { } , {
id: 25
price: 0
type: photo
} , {
id: 25
price: 0
type: photo
} ]
}
.filter is pretty much what you need.
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
var matches = $scope.invoice.items.filter(function(datum) {
return datum.id === $scope.item.id &&
datum.price === $scope.item.price &&
datum.type === $scope.item.type;
});
if (!matches.length)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
Semi-contrived JSFiddle
This is the solution I came up with to solve my problem, hopefully it helps someone else.
$scope.addPhoto = function () {
console.log('Withdrawing Photo: ' + $scope.item.id);
var newItemId = $scope.item.id;
var newItemPrice = $scope.item.price;
var newItemType = 'photo';
var matches = true;
// Make sure user hasnt already added this item
angular.forEach($scope.invoice.items, function(item) {
if (newItemId === item.id && newItemPrice === item.price && newItemType === item.type) {
matches = false;
$scope.message = 'You have already selected to withdraw this item!';
}
});
// add item to collection
if (matches != false) {
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
$scope.total += $scope.item.price;
$scope.message = 'Total Amount Selected';
}
};
YOu can simple pop opposite of push
array.splice(array.pop(item));