How do I access this javascript object and log it - javascript

I have been developing an app with ionic. And I have used SQLite. I have executed a query but I can't console log the value. Here's the code snippet:
var query = "SELECT SUM(total) FROM items";
console.log(query);
$cordovaSQLite.execute(db, query, []).then(function (res) {
console.log(res.rows[0]);
$scope.grand = {};
$scope.grand = res.rows[0];
console.log($scope.grand.SUM);
}, function (err) {
console.error("error=>" + err);
});
I want to directly console log the value of SUM(total). But, the log shows like below:
Object {SUM(total): 400}
SUM(total):400
How do I directly console log 400?

I would guess it should work like this:
console.log(res.rows[0]['SUM(total)']);
Because I always feel uncomfortable using characters like parentheses in a key name I would maybe prefer:
var query = "SELECT SUM(total) as mytotal FROM items";
and then:
console.log(res.rows[0]['mytotal']);
or
console.log(res.rows[0].mytotal);

Related

GlideAjax request doesn't return any response

I'm newer in servicenow developing.
I try to create a bundle "Script Include" - "Client Script".
Using background script I see, that my script include works fine.
But when I try to call this include via client script, it doesn't return any response.
Here is my method in Script Include:
usersCounter: function () {
var gr = new GlideRecord('sys_user');
gr.query();
var users = gr.getRowCount();
gs.info('Number of users'+ ' ' + users);
return users;
And here is my client script:
var ga = new GlideAjax('SCI_Training_ScriptIncludeOnChange');
ga.addParam('sysparm_name', 'usersCounter');
ga.getXML(getUsers);
function getUsers(response) {
var numberOfUsers = response.responseXML.documentElement.getAttribute("answer");
g_form.clearValue('description');
console.log(numberOfUsers);
And I have null in my console.
What have I missed?
Irrespective of why it's not working, you probably want to change your server side GlideRecord to use GlideAggregate instead, and just let mysql return the row count:
var gr = new GlideAggregate('sys_user');
gr.addAggregate('COUNT');
gr.query();
gr.next();
var users = gr.getAggregate('COUNT');
gs.info('Number of users'+ ' ' + users);
return users;
Doing a GlideRecord#query with no where clause is essentially doing a "SELECT * FROM sys_user", bringing over all the data, when all you're asking for is the row count from the metadata in the result set.
Beyond that, make sure your Script Include properly extends AbstractAjaxProcessor and has the client-callable field set to true per this:
https://docs.servicenow.com/bundle/geneva-servicenow-platform/page/script/server_scripting/reference/r_ExamplesOfAsynchronousGlideAjax.html
You can try to debug your getUsers() method. Try to check what the object structure of response is.
You could also use
var ga = new GlideAjax('SCI_Training_ScriptIncludeOnChange');
ga.addParam('sysparm_name', 'usersCounter');
ga.getXMLAnswer(getUsers);
function getUsers(response) {
var numberOfUsers = response;
g_form.clearValue('description');
console.log(numberOfUsers);
}

MongoDB - Mongoose - TypeError: save is not a function

I am attempting to perform an update to a MongoDB document (using mongoose) by first using .findById to get the document, then updating the fields in that document with new values. I am still a bit new to this so I used a tutorial to figure out how to get it working, then I have been updating my code for my needs. Here is the tutorial: MEAN App Tutorial with Angular 4. The original code had a schema defined, but my requirement is for a generic MongoDB interface that will simply take whatever payload is sent to it and send it along to MongoDB. The original tutorial had something like this:
exports.updateTodo = async function(todo){
var id = todo.id
try{
//Find the old Todo Object by the Id
var oldTodo = await ToDo.findById(id);
}catch(e){
throw Error("Error occured while Finding the Todo")
}
// If no old Todo Object exists return false
if(!oldTodo){
return false;
}
console.log(oldTodo)
//Edit the Todo Object
oldTodo.title = todo.title
oldTodo.description = todo.description
oldTodo.status = todo.status
console.log(oldTodo)
try{
var savedTodo = await oldTodo.save()
return savedTodo;
}catch(e){
throw Error("And Error occured while updating the Todo");
}
}
However, since I don't want a schema and want to allow anything through, I don't want to assign static values to specific field names like, title, description, status, etc. So, I came up with this:
exports.updateData = async function(update){
var id = update.id
// Check the existence of the query parameters, If they don't exist then assign a default value
var dbName = update.dbName ? update.dbName : 'test'
var collection = update.collection ? update.collection : 'testing';
const Test = mongoose.model(dbName, TestSchema, collection);
try{
//Find the existing Test object by the Id
var existingData = await Test.findById(id);
}catch(e){
throw Error("Error occurred while finding the Test document - " + e)
}
// If no existing Test object exists return false
if(!existingData){
return false;
}
console.log("Existing document is " + existingData)
//Edit the Test object
existingData = JSON.parse(JSON.stringify(update))
//This was another way to overwrite existing field values, but
//performs a "shallow copy" so it's not desireable
//existingData = Object.assign({}, existingData, update)
//existingData.title = update.title
//existingData.description = update.description
//existingData.status = update.status
console.log("New data is " + existingData)
try{
var savedOutput = await existingData.save()
return savedOutput;
}catch(e){
throw Error("An error occurred while updating the Test document - " + e);
}
}
My original problem with this was that I had a lot of issues getting the new values to overwrite the old ones. Now that that's been solved, I am getting the error of "TypeError: existingData.save is not a function". I am thinking the data type changed or something, and now it is not being accepted. When I uncomment the static values that were in the old tutorial code, it works. This is further supported by my console logging before and after I join the objects, because the first one prints the actual data and the second one prints [object Object]. However, I can't seem to figure out what it's expecting. Any help would be greatly appreciated.
EDIT: I figured it out. Apparently Mongoose has its own data type of "Model" which gets changed if you do anything crazy to the underlying data by using things like JSON.stringify. I used Object.prototype.constructor to figure out the actual object type like so:
console.log("THIS IS BEFORE: " + existingData.constructor);
existingData = JSON.parse(JSON.stringify(update));
console.log("THIS IS AFTER: " + existingData.constructor);
And I got this:
THIS IS BEFORE: function model(doc, fields, skipId) {
model.hooks.execPreSync('createModel', doc);
if (!(this instanceof model)) {
return new model(doc, fields, skipId);
}
Model.call(this, doc, fields, skipId);
}
THIS IS AFTER: function Object() { [native code] }
Which showed me what was actually going on. I added this to fix it:
existingData = new Test(JSON.parse(JSON.stringify(update)));
On a related note, I should probably just use the native MongoDB driver at this point, but it's working, so I'll just put it on my to do list for now.
You've now found a solution but I would suggest using the MongoDB driver which would make your code look something along the lines of this and would make the origional issue disappear:
// MongoDB Settings
const MongoClient = require(`mongodb`).MongoClient;
const mongodb_uri = `mongodb+srv://${REPLACE_mongodb_username}:${REPLACE_mongodb_password}#url-here.gcp.mongodb.net/test`;
const db_name = `test`;
let db; // allows us to reuse the database connection once it is opened
// Open MongoDB Connection
const open_database_connection = async () => {
try {
client = await MongoClient.connect(mongodb_uri);
} catch (err) { throw new Error(err); }
db = client.db(db_name);
};
exports.updateData = async update => {
// open database connection if it isn't already open
try {
if (!db) await open_database_connection();
} catch (err) { throw new Error(err); }
// update document
let savedOutput;
try {
savedOutput = await db.collection(`testing`).updateOne( // .save() is being depreciated
{ // filter
_id: update.id // the '_id' might need to be 'id' depending on how you have set your collection up, usually it is '_id'
},
$set: { // I've assumed that you are overwriting the fields you are updating hence the '$set' operator
update // update here - this is assuming that the update object only contains fields that should be updated
}
// If you want to add a new document if the id isn't found add the below line
// ,{ upsert: true }
);
} catch (err) { throw new Error(`An error occurred while updating the Test document - ${err}`); }
if (savedOutput.matchedCount !== 1) return false; // if you add in '{ upsert: true }' above, then remove this line as it will create a new document
return savedOutput;
}
The collection testing would need to be created before this code but this is only a one-time thing and is very easy - if you are using MongoDB Atlas then you can use MongoDB Compass / go in your online admin to create the collection without a single line of code...
As far as I can see you should need to duplicate the update object. The above reduces the database calls from 2 to one and allows you to reuse the database connection, potentially anywhere else in the application which would help to speed things up. Also don't store your MongoDB credentials directly in the code.

Node js mysql syntax error

I write some code in the server-side, in node js for update MySQL database.
this is my code:
exports.addPlayerToMatch = function(uid,matchId){
return new Promise(function(resolve,reject){
dbFunctions.getPlayerUids(matchId).then(function(rows){
playerUids = JSON.parse(rows[0].uids_of_players);
playerUids.push(uid);
console.log("new player uids: " +playerUids);
numberOfPlayers = playerUids.length;
db.query('UPDATE current_matches SET number_of_players = ?,
uids_of_players = ? WHERE id = ?' ,[numberOfPlayers,playerUids,matchId],
function (err, rows) {
if (err){ console.log("ErrorForAddPlayerToMatch: "+err);}
});
resolve(numberOfPlayers);
});
});
};
and this is the error:
ErrorForAddPlayerToMatch: Error: ER_PARSE_ERROR: You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''3d8b7210fc1999bf191b0e1f7d744269' WHERE id = 29' at line 1
I have no idea !!
help, please.
The Problem was that I forgot to turn an array into a JSON object again before using it in the query.
it will solve with something like this:
var playerUids = JSON.stringify(playerUids);
and then use it in the query.

How to update array to firebase?

I am new in this field. I see there are many ways on the internet and most of them is about the old version of Firebase, like using push(), update(), save(). So, I really don't know how to update it. I tried that like this:
function writeNewEvent(eObj) {
// A post entry.
var userObj = authObj.$getAuth();
// Get a key for a new Post.
var newEventKey = ref.child('events').child(userObj.uid).push().key;
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/events/' + userObj.uid+ '/' + newEventKey] = userObj;
return ref.update(updates);
}
But the error is:
angular.js:13920 Error: Firebase.update failed: First argument contains an invalid key ($d) in property 'events.LRnkjDgEu1QtuvUTazTwyms4U063.-KW56c87MThrK0PZp-XH.f'. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"
Could you tell me if my method is correct? And how to implement this function.
It looks like you have an ID so you don't need to use push(), just set() at the id like:
// assuming your input looks somthing like:
let eObj = {
"uuid": "98765-8765-1234567890-7890",
"some-data": "stuff",
"other-data": "other stuff",
"numeric-data": 12345
}
function writeNewEventUsingObjUuid(eObj) {
// A post entry.
var userObj = authObj.$getAuth();
return ref.child('events').child(userObj.uid).set(eObj).then(function () {
console.log('Event added with ID: ' + userObj.uid);
}).catch(function (e) {
console.log('Error adding event: ' + e.message);
});
}
If you really want to use push(), firebase will assign you an ID. Note that an empty push() like you had returns a thenable reference. The work is still done asynchronously event though you get an ID upfront.

Ways to do a dynamic query in node.js

I'm trying to figure out how to do dynamic queries in node.js with node-mysql. Which table and fields to insert and update is based on users' request from the data object. I thought of creating a module to store different queries like the following but no luck. It gave me this error:
TypeError: Object function (){
var likes = 'INSERT IGNORE INTO item (id,like_type) VALUES(?,?)';
return likes;
} has no method 'replace'
app.js
var queries = require('./queries');
.....
socket.on("like",function(data){
var table_file = data[0].table;
var d = data[1];
connection.query(queries[table_file]
,[d.id,d.like_type],function(err,rows,fields){
if(err){ throw err;}
console.log(rows);
});
queries.js:
module.exports = {
item_like:function(){
var likes = 'INSERT IGNORE INTO item (id,like_type) VALUES(?,?)';
return likes;
},
people:function(){
var likes = 'INSERT IGNORE INTO people (id,like_type) VALUES(?,?)';
return likes;
}
}
Here's the data object sent to socket:
data object: {table:item_like},{id:1,like_type:1};
Change your exports in queries.js to be set to the SQL strings instead of functions, since that is how you're treating them currently:
module.exports = {
item_like: 'INSERT IGNORE INTO item (id,like_type) VALUES(?,?)',
people: 'INSERT IGNORE INTO people (id,like_type) VALUES(?,?)'
}

Categories

Resources