I am using sequelize to run a raw MSSQL update query. The documentation for raw update queries states that the message for number of rows updated will be contained in the metadata. In the following function both results and metadata are undefined on update statements. It works perfectly fine if I use a normal select statement.
Documentation
The section in reference is the very first example.
Could someone help me understand what I am doing incorrectly?
var query = 'UPDATE contacts SET aolid = 1 WHERE contactid = 804748'
connection.query(query).spread(([results, metadata]) => {
console.log(metadata) // will log undefined
console.log(results) // will log undefined
})
Either use
.then(([results, metadata]) =>
or
.spread((results, metadata) =>
but .spread(([results, metadata]) => will not work. See spread().
Related
I have a web application built on Node.js and I use Knex as my db tool. It has all worked perfectly for months, but now, one of the columns in my db is not updating correctly. I have the columns 'base','bonus','production_bonus','deductions' and 'commission_earned'. The 'commission_earned' column is calculated on the backend of the application and then the values are sent to the db with knex. It is working perfectly for the initial creation of the record, but when I edit the record, it is not updating the 'commission_earned' column correctly. It updates the other values correctly, and when I console.log() the value to be stored for commission_earned it shows the correct value, it just is not updating it.
I have included screenshots of my code below as well as an example for you to see. I tried copying the column name from postgres to ensure it wasn't misspelled and it still doesn't work. So far, I have tried the following:
Ensured that all of the column names are being used correctly
Tried using a separate update call to update the value after updating the other values
Created a postgres function with a trigger that should update the column value any time a row is added
Tried using knex.raw to run the query that way
Tried placing the update method after the where clause in knex
I am stuck at this point and have no idea what to do.
P.S I know this db is not properly normalized, I built it when I was first learning how to build with Node
This is my index.js
When I console.log myData.commission_earned, it returns the correct value, but it does not update it in the db
app.post("/editScore", async (req,res) => {
var score_id = req.body.scoreID;
const myData = await calculateCommission.getData(req.body);
knex('commissions').update(myData).where('id',score_id)
.then( () => {
res.redirect("/commissionLog")
})
});
Below is the code for the initial log, it is working correctly, and they both calculate the commission_earned with the same function
app.post("/submitCommission", async (req,res) => {
//take the data sent in the request and send it to the commissionCalc file for processing
const myData = await calculateCommission.getData(req.body);
//Insert values into DB
knex("commissions").insert(myData)
.then( () => {
res.redirect("/commissionLog")
})
})
I know it is not an issue with the calculation itself since I am able to console.log() and see that the correct value is being returned. And like I mentioned, it is updating the other values correctly, just not the commission_earned column.
I was finally able to get this to work by doing the following
app.post("/editScore", async (req,res) => {
var score_id = req.body.scoreID;
calculateCommission.getData(req.body).then( myData => {
knex('commissions').update(myData).where('id',score_id)
.then( () => {
knex('commissions').update('commission_earned',myData.commission_earned).where('id',score_id).then( () => {
res.redirect("/commissionLog")
})
})
})
});
Gratz for you to solved it! however i still don't think it's normal for you to do 2 operations in your database with the same data, it feel like you have to hard code to make it work and i am sure there is better and more elegant solution, i check again in the Knex documentation, how about you try again but "destructure" out your data? like this:
app.post("/editScore", async (req,res) => {
const score_id = req.body.scoreID;
const myData = await calculateCommission.getData(req.body);
await knex('commissions')
.where('id',score_id)
.update({
foo1: myData.foo1,
foo2: myData.foo2,
foo3: myData.foo3, //...since i don't know how is your data stucture
commission_earned: myData.commission_earned
})
res.redirect("/commissionLog")
Btw you can remove your Async keyword in your answer since you use only promise, as for me i am using here async/await, but this is just personal preference.
Given the following data struct in firebase, I wish to retrieve the field in just standard JS. I have tried many methods of getting it, but for some reason, I cannot. I have tried .get(), forEach(), I have tried getting a snapshop, but it won't work.
At the start of my JS file I do:
const auth = firebase.auth();
const db = firebase.firestore();
let totalGroups;
db.collection('totalGroups').doc('totalGroups').get().then(function(querySnapshot) {
querySnapshot.docs.forEach(function(doc) {
if (doc.data().totalGroups != null) {
totalGroups = doc.data().totalGroups console.log("here is total groups" + totalGroups)
//Total Groups is undefined out here but defined in fuction
}
})
})
and normally I am able to get .get() just fine. I am looking for the most simple method of getting this value. thanks.
First, you are using get() on a DocumentReference which returns a DocumentSnapshot containing data of that single document only and has no docs property on it. Try refactoring the code as shown below:
db.collection('totalGroups').doc('totalGroups').get().then(function(snapshot) {
const docData = snapshot.data();
console.log(docData)
})
Also do note that if you were using get() on a CollectionReference, then it would have returned a QuerySnapshot where the existing code works fine.
This is definitely a newbie question, and in part answered in the Firebase documentation, but for the life of me it's not working when implementing it in my own code - so I'm hoping the community can help me understand what I am doing wrong, and how to fix it.
When getting documents from Firestore, I can't access the actual values within, due to its structure, so when setting e.g. "var name = doc.name" it just gives me undefined. For getting MULTIPLE documents, I've already found apiece of code that works:
// Getting the document
docRef.collection(collectionRef).get()
.then((snapshots) => cleanData(snapshots))
.then((items) => items.map((item) => sampleFunction(item)));
// Firebase Utility cleaning documents (array)
function cleanData(snapshots) {
let data = [];
snapshots.forEach(function(doc) {
data.push({
id: doc.id,
...doc.data()
});
});
return data;
}
But when using this piece of code with e.g. collection("x").doc("id"), then it throws the error:
"Uncaught (in promise) TypeError: snapshots.forEach is not a function"
So I went ahead to modify the function as follows:
// Firebase Utility cleaning document (single)
function cleanDoc(snap) {
let data = [];
data.push({
id: doc.id,
...doc.data()
});
return data;
}
But that gives me "undefined" when attempting to access the values in my function again...
The documentation (in the city example) says to define a class. When I did that, I was able to get values from one document, but it gave me undefined the second time I called the same function on one page.
For context, I'm trying to display a User Profile, which displays people they work with on a project, which means I call these profiles as well, the data structure just callsa reference to the "worked with" profiles, and I get their ID's just fine, but when attempting to render an HTML item for each, the values within their profiles are undefined....Its confusing the hell out of me anyways.
If your function is an async function:
collectionSnap = await docRef.collection(collectionRef).get();
val items=[]
await Promise.all(querySnap.docs.map(async (doc) => {
// Do your your work and populate items
}));
// Do your work with items
You can try this approach to processing your documents.
Trying to remove an item from the firebase array using arrayRemove but I'm getting the following error:
ReferenceError: Can't find variable: FieldValue
const removeItemHandler = () => {
//this logs the array item like is should, dont think this value is the issue
console.log(props.item)
console.log(props.currentNote)
//removes note from the notes array
db.collection('users').doc(userEmail)
.collection('books').doc(props.currentBook)
.collection('specific').doc(props.currentNote).update({
notes: FieldValue.arrayRemove(props.item)
})
showRemoveButton(false)
}
I was following the example linked below, really not sure why my, very similar situation is giving me this error. Thank you!
https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html
also, keep in mind that props.item is referencing the array items name, I checked the type and the value with the console.log's and it is correct. Confident that is not part of the issue.
You are accessing FieldValue which is undefined. You cannot access it directly.
You can access it via firebase.firestore.FieldValue or if you imported firestore directly then firestore.FieldValue. So change your code like this :
const removeItemHandler = () => {
//this logs the array item like is should, dont think this value is the issue
console.log(props.item)
console.log(props.currentNote)
//removes note from the notes array
db.collection('users').doc(userEmail)
.collection('books').doc(props.currentBook)
.collection('specific').doc(props.currentNote).update({
notes: firebase.firestore.FieldValue.arrayRemove(props.item)
notes: firestore.FieldValue.arrayRemove(props.item) // or if you are imported firestore
})
showRemoveButton(false)
}
I've been trying to make a prevButton for a pagination, using firestore and trying to use limitToLast().
When I run the code I get an error saying limitToLast is not a function.
Uncaught TypeError: db.collection(...).orderBy(...).endBefore(...).limitToLast is not a function
My code:
prevButton.addEventListener('click', () => {
db.collection('posts')
.orderBy('likes', 'asc')
.endBefore(firstDocument) // <-- The first document on view
.limitToLast(3) // <-- LimitToLast is not a function ???
.onSnapshot((snapshot) => loadDocuments(snapshot));
});
If I remove limitToLast() my code runs without error, but of course it doesn't work as intended.
Gods of stackoverflow, what am I doing wrong here?
This is the code I made based on Frank's answer, in case someone finds it useful.
prevButton.addEventListener('click', () => {
db.collection('posts')
.orderBy('likes', 'desc') // Reverse the sort order
.startAfter(firstDoc) // First doc in view
.limit(postPorPagina) // Limit the results
.onSnapshot((snapshot) => {
const documents = snapshot.docs.reverse(); // Reverse the documents again
renderDocuments(documents); // Function that renders my documents on screen.
});
});
limitToLast is a method on the Firebase Realtime Database API. You are accessing Cloud Firestore, which has a separate (though sometimes similar) API.
The only method to limit results on Firestore is limit(...). If you want the same behavior as limitToLast from Realtime Database, you'll have to:
Reverse the sort order
Limit to the correct number of results
Reverse the results client-side