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.
Related
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.
I have a fully functioning CRUD app that I'm building some additional functionality for. The new functionality allows users to make changes to a list of vendors. They can add new vendors, update them and delete them. The add and delete seem to be working just fine, but updating doesn't seem to be working even though it follows a similar method I use in the existing CRUD functionality elsewhere in the app. Here's my code:
// async function from AXIOS request
const { original, updatedVendor } = req.body;
let list = await Vendor.findOne({ id: 1 });
if (!list) return res.status(500).json({ msg: 'Vendors not found' });
let indexOfUpdate = list.vendors.findIndex(
(element) => element.id === original.id
);
list.vendors[indexOfUpdate].id = updatedVendor.id;
list.vendors[indexOfUpdate].name = updatedVendor.name;
const updated = await list.save();
res.json(updated);
The save() isn't updating the existing document on the DB side. I've console logged that the list.vendors array of objects is, indeed, being changed, but save() isn't doing the saving.
EDIT:
A note on the manner of using save, this format doesn't work either:
list.save().then(res.json(list));
EDIT 2:
To answer the questions about seeing the logs, I cannot post the full console.log(list.vendors) as it contains private information, however, I can confirm that the change made to the list is showing up when I run the following in the VendorSchema:
VendorSchema.post('save', function () {
console.log(util.inspect(this, { maxArrayLength: null }));
});
However, the save still isn't changing the DB side.
Since you are using nested objects, Mongoose will not be able to detect the changes made. You need to mark the modified as an object before the save
list.markModified('vendors');
First time poster here!
While I was trying to build a little exercise organizer application with ReactJS and Firebase realtime database I encountered a problem with the Firebase push() method.
I have a couple elements on my page that push data to the database once they are clicked, which looks like this:
const planRef = firebase.database().ref("plan");
const currentExName = e.currentTarget.firstChild.textContent;
const exercise = {
name: currentExName,
type: e.currentTarget.children[1].textContent,
user: this.state.user.displayName
};
planRef.push(exercise);
Also, if the element is clicked again, then it gets removed from the database like this:
planRef.orderByKey().on("value", snapshot => {
let exercises = snapshot.val();
for (let ex in exercises) {
if (exercises[ex].name === currentExName) {
planRef.child(ex).set(null);
}
}
});
This is working fine as long as I don't try to push something to the database when I just deleted the last bit of data from it. In that case it gets removed right away.
Data getting removed
Summary:
Write data to the realtime database using ref.push()
Delete data using ref.child(child).set(null) (I tried remove() before, same problem)
Try to push the same data to the database again which leads to the data getting deleted right after being written to the database
I couldn't find anything about this kind of problem so far so I guess I might have made a mistake somewhere. Let me know if the information provided is not sufficient.
Thanks in advance.
Removing a child is an asynchronous operation. I guess what is happening here is the removing operation takes more time than the new writing operation. You will need to await for it if you want to write again on the same key.
planRef.child(ex).set(null).then(() => {
planRef.child(ex).push(new);
});
Or using async/await:
await planRef.child(ex).set(null);
planRef.child(ex).push(new);
Let me know if it worked.
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().