How to update multiple collection keys received as arguments? - javascript

I'm trying to increase different values in my collection using the same code.
I'm trying to compute that in a function where the updated properties will depend on the parameters:
BuyEntitee : function(id_fb,entitee)
{
var j = Joueur.findOne({id_fb:id_fb});
var prix_current = j["prix_"+entitee];
var update_query = {};
update_query[entitee+"s"] = j[entitee+"s"] + 1;
update_query["prix_"+entitee] = Math.round(50*Math.pow(1.1,j[entitee+"s"]));
Joueur.update( {id_fb:id_fb}, {
$set: {update_query}
}
);
j = Joueur.findOne({id_fb:id_fb}); // on recharge le jouer ... utile ??
console.log('nbHumains : ' + j.humains+ ' query = '+JSON.stringify(update_query));
return j.rochers;
}
But unfortunately, the query is 1 level too deep in the structure :
meteor:PRIMARY> db.joueur.findOne()
{
"_id" :
"humains" : 12,
"prix_humain" : 50,
"update_query" :
{
"humains" : 13,
"prix_humain" : 157
}
}
I'm creating the update_query object so that I can programmatically change the parameters in the update function (saw this here).
Is there a way to perform that?

What happened is, in fact, a result of the ES6 syntactic sugar for specifying objects.
When you specified {update_query}, it was interpreted as an object with the key of "update_query" and the value of the variable update_query.
Therefore, it is the equivalent of:
Joueur.update( {id_fb:id_fb}, {
$set: {
update_query: update_query
}
}
);
What you really want is to assign the update_query itself to the $set key:
Joueur.update( {id_fb:id_fb}, {
$set: update_query
}
);
On a side note, you probably want to use the $inc modifier in order to increment the entitee+"s" by 1.

Related

Pg-promise performance boost : Multiple inserts with multiple update parameters

I am implementing Vitaly's pg-promise performance patterns, as advised here and there.
Here is my code :
for (var i=0;i<chunkedData.length;i++){
var insertData = chunkedData[i].map(function (d) {
return {
application_id: d.application_id,
country_id: d.country_id,
collection_id: collectionId
};
});
// Would need to make a loop here, and thus turning the result into an array
var updateData = {
application_id: chunkedData[i][j].application_id,
country_id: chunkedData[i][j].country_id,
collection_id: collectionId
};
var query = h.insert(insertData, cs) +
" ON CONFLICT ON CONSTRAINT application_average_ranking_application_id_country_id_colle_key DO UPDATE SET " +
h.sets(updateData, cs);
db.none(query)
.then(data => {
console.log('success');
})
.catch(error=> {
console.log('insert error : ' + error);
});
}
My problem is that insertData is an Array of Objects, and the library's insert helper builds an insert request using that Array, as specified in pg-promise API. Whereas updateData must be a simple Object.
I would like that when :
ON CONFLICT ON CONSTRAINT constraintName DO UPDATE
is triggered, the update values match the corresponding object in 'insertData' array.
How can I work around that problem ?
I've tried to put everything in a loop, but it leaks memory like crazy, and well, I lose the benefits of the pattern...
EDIT :
I want my query to be the equivalent of :
var inserts = data.map(entry => {
return t.none(" INSERT INTO application_average_ranking (application_id,country_id,collection_id) VALUES ($1,$2,$3)" +
" ON CONFLICT ON CONSTRAINT application_average_ranking_application_id_country_id_colle_key" +
" DO UPDATE SET country_id=$2,collection_id=$3",
[entry.application_id,entry.country_id,collectionId]
);
});
In that case when Update is called, the parameters refer to values originally proposed for insertion.
Your task requires a static SQL to implement that kind of logic, by using EXCLUDED as the table reference with rows excluded due to the conflict:
var sqlConflict = " ON CONFLICT ON CONSTRAINT" +
" application_average_ranking_application_id_country_id_colle_key" +
" DO UPDATE SET application_id = excluded.application_id" +
" country_id = excluded.country_id, collection_id = excluded.collection_id";
var insertData = chunkedData.map(function (d) {
return {
application_id: d.application_id,
country_id: d.country_id,
collection_id: collectionId
};
});
var query = h.insert(insertData, cs) + sqlConflict;
db.none(query)
.then(data => {
console.log('success');
})
.catch(error=> {
console.log('insert error : ' + error);
});
UPDATE
And in case your static list of excluded fields is too long and you want to simplify it, you can can always rely on flexibility of the helpers methods:
// or pull them from an object using `Object.keys(obj)`:
var cols = ['application_id', 'country_id', 'collection_id'];
var sets = pgp.helpers.sets({}, cols.map(c=> ({
name: c, mod: '^', def: 'excluded.' + pgp.as.name(c)
})));
console.log(sets);
//=> "application_id"=excluded."application_id","country_id"=excluded."country_id",
// "collection_id"=excluded."collection_id"
// or its simple JavaScript equivalent:
var sets = cols.map(c=> {
var name = pgp.as.name(c);
return name + '=excluded.' + name;
}).join();
UPDATE
With version 7.3.0 of the library and later, you should use method assignColumns to generate all of the excluded sets, like this:
cs.assignColumns({from: 'EXCLUDED'})
//=> "application_id"=EXCLUDED."application_id","country_id"=EXCLUDED."country_id","collection_id"=EXCLUDED."collection_id"
or, if you want to skip application_id, then you can do:
cs.assignColumns({from: 'EXCLUDED', skip: 'application_id'})
//=> "country_id"=EXCLUDED."country_id","collection_id"=EXCLUDED."collection_id"
See ColumnSet.assignColumns
Don't use h.sets(). Just write the conflict_action yourself. Handbook says
The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table's name (or an alias), and to rows proposed for insertion using the special excluded table.
Postgres - Insert

Store object inside object and update

I am trying to store an array inside and object like this:
var fieldData = {
checkedItem: {
fieldID : “1234”,
SelectedFields : []
}
checkedItem: {
fieldID : “12345”,
SelectedFields : []
}
}
I then want to also replace all selected fields to this object at a later stage.
I am a newbie to this so not sure how it would be done, I have tried everything I can think of!
The later changes to the object will referenced by fieldID.
I have tried stuff like:
fieldData["fieldID"] = selectedFieldSeq;
fieldData[selectedFieldSeq]["SelectedFields"] = $('#Tree').jqxTree('getCheckedItems');
$('#Tree').jqxTree('getCheckedItems');
returns an array of checked items on my tree.
This should do it:
'fieldID = $('#Tree').jqxTree('getCheckedItems');'
'fieldData.SelectedFields = fieldID'
There is a problem with this line :
fieldData[selectedFieldSeq]["SelectedFields"]
fieldData[selectedFieldSeq] is not defined, so it's return undefined
You need to initialize it before using it :
if (!fieldData[selectedFieldSeq]) {
fieldData[selectedFieldSeq] = {
SelectedFields : []
};
}
After, you can assign some value to SelectedFields.
Or did you want to simply do this : fieldData.SelectedFields = ...; ?

Issue Pushing values in to objects Javascript

Have some issue with push the values in to the javascript array object. Please any one give me the perfect solution
Class code :
var myfuns = ( function(undefined) {
var myarr ={};
function _add(arrayparam){
if (myarr.current == undefined) {
myarr.current = [];
myarr.current.push(options.current_info);
}else{
}
}
function _getList() {
return $.extend(true, {}, myarr);
}
return {
add : _add,
getList : _getList
}
}());
Here am calling and manage the values and keys
function setmydetails(){
var my_param = {
current_info : {
pg : '#tset',
no : 12,
name : "john",
row : 0,
},
userprofile : [],
class : [],
marks : [],
games : []
};
myfuns.add(my_param);
}
Now i got the array
myfuns.getList() // GOT proper array what i passed in my_param
Question : How to modify the existing values from any one of the Inner array from the myarr Obj
Ex: Once First array created later have to modify some from "myarr.current" = > Change current_info.row to 2222
Similar i have to add some array in to " myarr.class " etc
I would like to say try this one not tested
function _add(arrayparam){
if (myarr.current == undefined) {
myarr.current = [];
myarr.current.push(options.current_info);
}else{
$.extend( myarr.current, arrayparam);
}
}
proper source : https://api.jquery.com/jquery.extend/

Javascript multidimensional object overwriting last inserted item

I am trying to get a MD object in javascript, I have something this at the moment, but it isn't exactly what I want:
{"usernames":["Ted","Mikey"],"room_status":[0,0]}
The idea is that I want the room status values of 0 assigned to Ted and Mikey at the moment they are not. So I can then use:
$.each(usernames, function(index, value){
//do stuff
})
... to loop through the names and see which room status value is assigned to who.. I also tried something along the lines of this:
usernames = {
'username' : {
'username' : username,
'room_status' : 0
}
}
which returns:
{"username":{"username":"asdfgasdc","room_status":0}}
but overwrites the last item...
var users = [{
username: 'Ted',
room_status: 0
}, {
username: 'Mikey',
room_status: 0
}];
This gives you an array of objects, which you can either loop or access directly
$.each(users, function(index, user){
console.log(user.username + ' - ' + user.room_status);
});
// Ted - 0
// Mikey - 0
var user = users[0];
console.log(user.username + ' - ' + user.room_status);
// Ted - 0
You could easily use the usernames as keys:
var people = {
Mike: { room_status: 0 },
Ted: { room_status: 0 }
}
And loop through them with a for loop:
for(var person in people){
people[person].room_status
}
And even access them directly:
people.Mike.room_status
It would be more recommended to syphon everyone into a prototype and assign that to the username, as that way you can easily check for normals in your for loop (aka if( people[person] instanceof Person ) // run code, ignoring any possible default functions or prototype functions that may exist for an object.
change this
usernames = {
'username' : {
'username' : username,
'room_status' : 0
}
}
to
usernames[username] = {
'username' : username,
'room_status' : 0
}
Because the 'username' key will be overwritten for every loop
var usernames = {};
var usernamesList = ["Ted","Mikey"];
for(var i=0;i < usernamesList.length;i++){
var username = usernamesList[i];
usernames[username] = {
'username' : username,
'room_status' : 0
}
}
will give you
usernames : {
Ted:{username:'Ted',room_status:0},
Mikey:{username:'Mikey',room_status:0}
}
calling:
usernames['Ted'].room_status OR usernames.Ted.room_status will return 0

Getting data from dynamic mongodb embedded object node.js

I have a mongoDB structure that looks like this:
values : { [
oneValue : {
number: '20'
unit: 'g'
}
differentValue : {
number : '30'
unit : 'g'
}
]}
I am using node js this is what I do:
doc.values.forEach(function(err, idx) {
var object = doc.values[idx];
}
And what ends up happening is I can get an object that looks like this:
object = oneValue : {
number: '20'
unit: 'g'
}
But node does not recognize it as a JSON because when I try to do JSON.parse(object) it doesn't know how to handle it.
I want to be able to get at the number field dynamically. So I don't want to say doc.values[idx].oneValue because this is a pretend case and in the real case oneValue could be one of 1000 different things. Does anyone know how I can access the 'number' field with this structure?
figured it out...
after
var object = docs.values[idx]
do this:
var objAsJson = JSON.stringify(object);
JSON.parse(objAsJson, function(k, v) {
console.log(k + " " + v);
});
That will print out all the data in the embedded object and you don't have to know the name.

Categories

Resources