MongoDB & Unable to set value depending on variable name - javascript

Coming across something i thought would have worked, but does not.
I have the following function that takes an input and needs to update one value in the mongodb.
const updateSkillXP = (data) =>{
//data = { username:username, sk:sk, xp:100 }
const collection = db.collection('player');
let q = {username:data.username}
//craft a key depending on what skill code comes through.
let s = "skills."+data.sk;
u = {$set: {s : data.xp}}
return collection.updateOne(q,u,(err,res) =>{
if(err) console.log(err);
})
}
The MongoDB document looks as follows
player = {
x:0,
y:0,
username:"foo",
skills : { //I need one of the following to update.
atk:0,
str:0,
def:0,
hp:0
}
}
When I executed the above, it added 'S' Property, but i was expecting to change the value of say 'atk' to what ever xp came through?

Answer:
JavaScript set object key by variable
const updateSkillXP = (data) =>{
//data = { username:username, sk:sk, xp:100 }
const collection = db.collection('player');
let q = {username:data.username}
let s = "skills."+data.sk;
let obj = {};
obj[s] = data.xp;
u = {$set: obj}
return collection.updateOne(q,u,(err,res) =>{
if(err) console.log(err);
})
}

Related

I can't send data from my indexed database

I lose the reference of the "value" variable when it is no longer in the "onsuccess" context. I don't know how to make this function asymmetric.
getList(){
let transaction = this.db.transaction([this.db_name], "readwrite");
transaction.oncomplete= _ => {
console.log("Success")
}
transaction.onerror = _ => {
console.log("Error")
}
let value = []
let objectStore = transaction.objectStore(this.db_name)
objectStore.getAll().onsuccess = e => {
value = e.target.result;
};
console.log(value)
return value
}
When I console.log(value) I get an empty array.
If I wanted to take this data and put it directly in my HTML it would have worked and these are the only examples I managed to find on the internet

(node:31260) UnhandledPromiseRejectionWarning

In function called "readPlcDataWriteToDB" i need to wait for data come before return a response. How can i do it ?
i am getting an error in this code about this problem. When i add "await" like "newData = await data;" it is same result no effects.
Please help me for solve this. Tnx..
const asyncErrorWrapper = require("express-async-handler");
var nodes7 = require('nodes7'); // This is the package name, if the repository is cloned you may need to require 'nodeS7' with uppercase S
var conn = new nodes7;
const MachineState = require("../models/MachineState");
var newData;
var doneReading = false;
var doneWriting = false;
var variables = {
nMachine1 : 'DB7,BYTE0',
nMachine2 : 'DB7,BYTE1',
nMachine3 : 'DB7,BYTE2',
nMachine4 : 'DB7,BYTE3',
nMachine5 : 'DB7,BYTE4',
nMachine6 : 'DB7,BYTE5',
nMachine7 : 'DB7,BYTE6',
nMachine8 : 'DB7,BYTE7',
nMachine9 : 'DB7,BYTE8',
nMachine10 : 'DB7,BYTE9',
nMachine11 : 'DB7,BYTE10',
nMachine12 : 'DB7,BYTE11',
nMachine13 : 'DB7,BYTE12',
nMachine14 : 'DB7,BYTE13',
nMachine15 : 'DB7,BYTE14'
};
var data;
conn.initiateConnection({port: 102, host: '192.168.200.1', rack: 0, slot: 1}, connected); // slot 2 for 300/400, slot 1 for 1200/1500
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(function(tag) {return variables[tag];}); // This sets the "translation" to allow us to work with object names
conn.addItems(['nMachine1' , 'nMachine2' , 'nMachine3' , 'nMachine4' , 'nMachine5' , 'nMachine6' , 'nMachine7' , 'nMachine8' , 'nMachine9' , 'nMachine10' , 'nMachine11' , 'nMachine12' , 'nMachine13' , 'nMachine14' , 'nMachine15']);
}
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
//console.log(values);
console.log("Done reading.");
doneReading = true;
if (doneWriting) { process.exit(); }
data = values;
sendDataToDB(values);
}
const readPlcDataWriteToDB = asyncErrorWrapper(async (req,res,next) => {
await conn.readAllItems(valuesReady);
newData = data;
return res
.status(200)
.json({
success : true,
data : newData
});
});
const sendDataToDB = asyncErrorWrapper(async (req,res,next) => {
let allMachineStates = await MachineState.findOne();
allMachineStates.Machine.M1 = newData.nMachine1;
allMachineStates.Machine.M2 = newData.nMachine2;
allMachineStates.Machine.M3 = newData.nMachine3;
allMachineStates.Machine.M4 = newData.nMachine4;
allMachineStates.Machine.M5 = newData.nMachine5;
allMachineStates.Machine.M6 = newData.nMachine6;
allMachineStates.Machine.M7 = newData.nMachine7;
allMachineStates.Machine.M8 = newData.nMachine8;
allMachineStates.Machine.M9 = newData.nMachine9;
allMachineStates.Machine.M10 = newData.nMachine10;
allMachineStates.Machine.M11 = newData.nMachine11;
allMachineStates.Machine.M12 = newData.nMachine12;
allMachineStates.Machine.M13 = newData.nMachine13;
allMachineStates.Machine.M14 = newData.nMachine14;
allMachineStates.Machine.M15 = newData.nMachine15;
await allMachineStates.save();
console.log("PLC'den Alınan Verilere Göre Database Güncellendi");
});
module.exports = {
readPlcDataWriteToDB
};
enter image description here
Based on the documentation for nodes7, it appears that readAllItems does not return a Promise, but rather expects a callback. This means that await will not correctly wait for it, so the assignment to newData wouldn't work.
Either move the handling of newData to a callback, or try something like util.promisify to convert the library function to use Promises
It seems to me that you should put your await calls inside a try-catch structure. Like this:
try {
await myFunctionOne();
cons myConstOne = await myFunctionTwo();
.... whatever you need to put here ...
} catch(error) {
console.error(error);
}
From there you would get rid of the "Unhandled-Promise-Rejection" issue and you could see what is causing the problem.
Beside that, you may find useful these few tutorials about Async-Await, I myself learned from them and still sometimes refer to them.

How does one parent a channel to a category with a discord bot?

Basically there is no errors in the output but at the same time it's not doing what I'm trying to achieve.
Ive been tinkering with the script for 5 hours straight mixing up line positioning and now I got it to where it gives me the promise (my initial issue) but I cant parent the channel.
I've tried discord.js server and site, youtube, 2 other sites i forgot the name of but i cant crack it.
function setup(arguments, message){
var server = message.guild;
var name = message.author.username;
let searchquery = arguments.join("")
let cat = server.createChannel("Important", "category");
async function Channelmaker(Sent, obj){
try {
let chan = await server.createChannel(Sent, "Text");
//console.log(obj);
return chan
} catch(prom){
var chan2 = await server.createChannel(Sent, "Text");
return new Promise(resolve => {
var chan2 = server.createChannel(Sent, "Text", parent = obj);
resolve(chan2)
});
}
}
var holding
var chan = Channelmaker("⚖️ rules ⚖️", cat).then(value => {
console.log(value)
holding = value
value.parentID = cat
chan.setParent(cat.Id)
}).catch(error => {
// s
});
console.log("holding")
console.log(holding)
}
The category is not the parent of the "⚖️ rules ⚖️" channel that is created which is the opposite of what I'm trying to achieve
In Guild.createChannel(), use the options parameter including ChannelData, like so:
await server.createChannel(Sent, {
// You can omit the 'type' property; it's 'text' by default.
parent: obj
});

Update an Object in indexed db by ignoring a value

I have written the below code
updatePublication(projectName, publicationId, publicationObj, callback) {
let self = this;
this.initDatabase(function (db) {
let tx = self.db.transaction(self.PUBLICATIONS, self.READ_WRITE);
let store = tx.objectStore(self.PUBLICATIONS);
let index = store.index(self.PROJECT_NAME);
let request3 = index.openCursor(IDBKeyRange.only(projectName));
console.log("hrere");
request3.onsuccess = function () {
let cursor = request3.result;
if (cursor) {
let updateObject = cursor.value;
if (updateObject.publicationID == publicationId) {
updateObject.publicationObject = publicationObj;
cursor.update(updateObject);
callback(publicationId);
}
cursor.continue();
} else {
callback(publicationId);
}
};
});
}
But this give error:
I checked the cause of error. It is beacuse , publicationObj which is passed has an object named _requestObjectBuilder which is of the type Subscriber.
used somewhere in the code like this:
_requestObjectBuilder = interval(1000).pipe(tap(() => {}));
Is there any way i can modify my updatePublication code to ignore this value?
Does indexed db support a query for ignoring a value and saving the data?
Note: If i set publicationObj._requestObjectBuilder = undefined, the data gets saved to indexedDB. But this breaks the functionality where _requestObjectBuilder is used.
Fixed the issue by cloning the object and setting it to undefined
let clonedObject = Object.assign({}, publicationObject);
clonedObject._requestObjectBuilder = undefined;
Now i am updating the clonedObject

Javascript: Why object is not getting initialise on new api call however the string variable is?

I may be missing something basic as why is it happening.
GET: example.com/users
//gives all data
GET: example.com/users?status=1
//gives data with status = 1
GET: example.com/users // this does not work
gives same data as pervious API condition with status=1
On third hit, self.whereObj is not initialising to default empty object instead it takes previous value of {'status' = '1'}, however self.page and self.limit is taking default value if no query parameter is provided in query string.
example.com/users?limit=3, // takes override to 3 form default value of 5
example.com/users // self.limit takes default 5 and this works fine
So my question is why the self.limit (simple string variable) is initialising however self.whereObj is not ?
var Bookshelf = require('../../dbconfig').bookshelf;
Bookshelf.Collection = Bookshelf.Collection.extend({
limit: 5,
page: 1,
whereObj: {}
myFetch: function (query_params,expectedWhereFields) {
var self = this;
var whereObj = self.whereObj ; // this is not initializing
// var whereObj = {}; this is initialising
var page = self.page;
var limit = self.limit; //this is not showing nay initialisation error
for (var x in query_params) {
if (expectedWhereFields.includes(x)) {
whereObj[x] = query_params[x];
}
if (x === 'page') {
page = query_params[x];
}
if (x === 'limit') {
limit = query_params[x];
}
}
var offset = (page - 1) * limit;
function fetch() {
return self.constructor.forge()
.query({where: whereObj})
.query(function (qb) {
qb.offset(offset).limit(limit);
})
.then(function (collection) {
return collection;
})
.catch(function (err) {
return err
});
}
return new fetch();
}
});
module.exports = Bookshelf;
UPDATED
service.js
var Model = require('./../models/Users');
var express = require('express');
var listUsers = function (query_params, callback) {
var expectedWhereFields = ["type", "status", "name"];
Model.Users
.forge()
.myFetch(query_params, expectedWhereFields)
.then(function (collection) {
return callback(null, collection);
})
.catch(function (err) {
return callback(err, null);
});
};
module.exports = {
listUsers: listUsers
};
model/Users.js
var Bookshelf = require('../../dbconfig').bookshelf;
var Base = require('./base');
// Users model
var User = Bookshelf.Model.extend({
tableName: 'user_table'
});
var Users = Bookshelf.Collection.extend({
model: User
});
module.exports = {
User: User,
Users: Users
};
So my question is why the self.limit (simple string variable) is initialising however self.whereObj is not?
Because objects are reference values. When you set var whereObj = self.whereObj;, both refer to the same object, and when you copy the query parameters into the object properties you are effectively writing into your defaults instance. This does not happen with primitive values such as strings - they don't have mutable properties.

Categories

Resources