SQLite PUT method not working due to SequelizeUniqueConstraintError - javascript

I built a PUT method for updating/editing inserted/existing records in sqlite db and when firing the put method the following error message is pulled up in the network tab for the PUT request. The issue seems to be related to SequelizeUniqueConstraintError and it auto-creating an id on update. Any thoughts or known workarounds?:
{
"error":"An error has occured trying to create the user.",
"err":{
"name":"SequelizeUniqueConstraintError",
"errors":[
{
"message":"id must be unique",
"type":"unique violation",
"path":"id",
"value":1,
"origin":"DB",
"instance":{
"id":1,
"email":"el#gmail.com",
"password":"$2a$08$HnRjfTzqsvwzobMQYM8bT.IkPbTSe6aOxy50l8/cUuuVhOgbl513.",
"firstName":"el",
"lastName":"leo",
"jobDescription":"test",
"gains":"100",
"costs":"50",
"balance":50,
"isAdmin":null,
"youAgree":null,
"createdAt":"2019-03-03T09:39:31.295Z",
"updatedAt":"2019-03-26T19:03:21.665Z"
},
"validatorKey":"not_unique",
"validatorName":null,
"validatorArgs":[
]
}
],
"fields":[
"id"
],
"parent":{
"errno":19,
"code":"SQLITE_CONSTRAINT",
"sql":"INSERT INTO `Users` (`id`,`email`,`password`,`firstName`,`lastName`,`jobDescription`,`gains`,`costs`,`balance`,`isAdmin`,`youAgree`,`createdAt`,`updatedAt`) VALUES (1,'el#gmail.com','$2a$08$HnRjfTzqsvwzobMQYM8bT.IkPbTSe6aOxy50l8/cUuuVhOgbl513.','el','leo','test','100','50',50,NULL,NULL,'2019-03-03 09:39:31.295 +00:00','2019-03-26 19:03:21.665 +00:00');"
},
"original":{
"errno":19,
"code":"SQLITE_CONSTRAINT",
"sql":"INSERT INTO `Users` (`id`,`email`,`password`,`firstName`,`lastName`,`jobDescription`,`gains`,`costs`,`balance`,`isAdmin`,`youAgree`,`createdAt`,`updatedAt`) VALUES (1,'el#gmail.com','$2a$08$HnRjfTzqsvwzobMQYM8bT.IkPbTSe6aOxy50l8/cUuuVhOgbl513.','el','leo','test','100','50',50,NULL,NULL,'2019-03-03 09:39:31.295 +00:00','2019-03-26 19:03:21.665 +00:00');"
},
"sql":"INSERT INTO `Users` (`id`,`email`,`password`,`firstName`,`lastName`,`jobDescription`,`gains`,`costs`,`balance`,`isAdmin`,`youAgree`,`createdAt`,`updatedAt`) VALUES (1,'el#gmail.com','$2a$08$HnRjfTzqsvwzobMQYM8bT.IkPbTSe6aOxy50l8/cUuuVhOgbl513.','el','leo','test','100','50',50,NULL,NULL,'2019-03-03 09:39:31.295 +00:00','2019-03-26 19:03:21.665 +00:00');"
}
}
This is the sample PUT method for reference:
put (user) { console.log('put user: ', JSON.stringify(user)) var userId = user.id console.log('put userId: ', userId) return Api().put(users/${user.id}, user) // return Api().put('users', userId, user) }

Related

How can i return only the value with mongoose populate?

I'm using mongoose-paginate-v2 and also i'm using populate. It works but when i populate my field, the population returns an array and i want to put the name of the value inside of the field cajaID:
What i want to get:
{
"_id": "5aa23958-06a9-4ff1-b614-d112d81b2eSi",
"nombre": "Zone",
"cajaID": "Caja grande"
}
What i get:
{
"_id": "5aa23958-06a9-4ff1-b614-d112d81b2eSi",
"nombre": "Zone",
"cajaID": {
"nombre": "Caja grande"
}
}
My code:
await ZonesModel.paginate(query, { populate: {path: 'cajaID', select: { '_id': 0,'nombre':1}}}, function(err, doc) {
if (err) {
error = new Error(err);
error.status = 500;
throw error;
}
data = doc;
})
mongoose-paginate-v2 also has projection but when i want to access to the field "nombre" it doesn't work, just returns the value of the field which has the id of the another collection.
await model.paginate(query, { populate: {path: 'cajaID', select: { '_id': 0,'nombre':1}}, projection: { caja: "$cajaID" }}, function(err, doc) {
if (err) {
error = new Error(err);
error.status = 500;
throw error;
}
data = doc;
})
This code return this:
{
"_id": "5aa23958-06a9-4ff1-b614-d112d81b2eSi",
"nombre": "Zone",
"cajaID": {
"nombre": "Caja grande"
},
"caja": "5aa23958-06a9-4ff1-b614-d112d81b2eBa" // id of the another collection but i can't access to the nombre field
}
I realize that i can't filter after populate only with $lookup and $match. Therefore, in my frontend i'll use dropdowns for the ids and display the client's name and return the id of the selected user and pass it to my endpoint and it doesn't matter if i can't filter with the user's name because i can filter with their ids.
There is another alternative and that is by denormalizing the data, but I have data that doesn't changes very often, so the best alternative is with pupulate.

DynamoDB query with lambda (node.js) FilterExpression using contains

Here is the table structure. In posts column it is a list of strings
So I been reading and trying to use filterExpression with 'contains'. What documentation said in node.js just need to use a CONTAINS b where a can be a list and b for me is a string I am searching for.
var db = new doc.DynamoDB();
var params = {
TableName: "WIT_Search",
KeyConditionExpression: "#type = :tag and #key between :start AND :end",
FilterExpression: "#tag contains :post",
ExpressionAttributeNames: {
"#type": "type",
"#tag": "posts",
"#key": "key",
},
ExpressionAttributeValues: {
":tag": "tag",
":start": tag+"_",
":end": tag+"_999",
":post": postID
}
};
console.log(params);
db.query(params, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
console.log('Count =',data.Items.length);
if (data.Items.length > 0){
console.log("post exists in tag");
}else{
console.log("post doesnt exist in tag");
}
}
});
Whenever I do testing it gives me this message:
Unable to query. Error: {
"message": "Invalid FilterExpression: Syntax error; token: \"contains\", near: \"#tag contains (\"",
"code": "ValidationException",
}
The weird thing on AWS Console it works without the problem, just using in lambda with node.js it gives this error.
Here is the correct syntax.
FilterExpression : 'contains (#tag, :post)'

How to write find and update query in express.js?

I am using REST API(express.js and mongodb) and trying to update my document but it's not working. I don't know what is the error but can someone help me out to move forward? I have added my route and controller
Routes:
app.route('/articleupdation')
.post(article.updatearticle);
Controller:
exports.updatearticle = function(req, res) {
Article.findOne({
Username: 'xx',
Email: 'xx#gmail.com',
Info: 'Deactivate',
}, function(err, article) {
if (!err && article) {
article.Info = 'Active';
article.save(function(err) {
if (err) {
console.log('not working');
} else {
console.log('working');
}
});
} else {
console.log('Condtion not matched ');
console.log(err);
}
});
};
Data stored like this
{
"_id": {
"$oid": "5799995943d643600fabd6b7"
},
"Username": "xx",
"Email": "xx#gmail.com",
"Info": "Deactivate",
"Description": "aajdjdjddjdkjddjdjdhdj",
}
Here is what I am trying to achieve; if Username, Email, Info are matched I need to update article.Info = 'Active'; but this is not working, can someone help me out please?
From the looks of it, your query is not matching any documents in the collection hence the statement branch which does the update is not being reached, just the else statement as the returned article is null. You can test this by running the raw query in mongo shell on the underlying collection i.e.
db.articles.findOne({
"Username": "xx",
"Email": "xx#gmail.com",
"Info": "Deactivate"
})
and see if that returns any matching document. If not, check the Info field from the document returned in this query
db.articles.findOne({
"Username": "xx",
"Email": "xx#gmail.com"
})
The best way to go about this within an atomic update that does not require two requests to the server (i.e. one to query the document and the other to write the changes to the server) is to use the findOneAndUpdate api. This will issue a mongodb findAndModify update command which modifies and returns a single document. By default, the returned document does not include the modifications made on the update. To return the document with the modifications made on the update, use the new option.
Thus your refactored code could follow this pattern:
exports.updatearticle = function(req, res) {
Article.findOneAndUpdate(
{ "Username": req.body.username, "Email": req.body.email, "Info": "Deactivate" },
{ "$set": { "Info": "Active" } },
{ "new": true },
function (err, doc) {
if (err) { // err: any errors that occurred
console.log(err);
} else { // doc: the document before updates are applied if `new: false`
console.log(doc); // , the document returned after updates if `new true`
console.log(doc.Info);
}
}
);
};

How to update user.services for Jasmine testing in Meteor

I am trying to mock out a user for testing out my application, and I have gotten to the point where I can create a test user and log them into the mirror instance of my app.
I need to compare the gmail addresses for peoples accounts, and to test this functionality, I want to add a test email address under user.services.google.email within the Meteor users account database (which is where the accounts-google package stores it, I don't need to mock out an entire user account yet).
What I can't figure out is how to append this information, instead of just overwriting what is already there, this is what my code looks like:
if (Meteor.users.find().count() === 0) {
var testUserDetails = {
email: 'testEmail#gmail.com',
password: 'testPassword'
};
console.log("Creating the Test User");
var newUserId = Accounts.createUser(testUserDetails);
Meteor.users.update({
_id: newUserId
}, {
$set: {
services: {
google: {
email: "testEmail#gmail.com"
}
}
}
});
} else {
console.log("There are already users in the Test database");
}
console.log('***** Finished loading default fixtures *****');
},
And this is what a user looks like:
{
"_id" : "Dw2xQPDwKp58RozC4",
"createdAt" : ISODate("2015-07-30T04:02:03.261Z"),
"services" : {
"password" : {
"bcrypt" : "asdfasdfasdfdsafsadfasdsdsawf"
},
"resume" : {
"loginTokens" : [ ]
}
},
"emails" : [
{
"address" : "testEmail#gmail.com",
"verified" : false
}
]
}
Now $set just rewrites everything within services, and there is no $push operation for mongo or for js, so how should I go about doing this? Should I consume the object and parse it manually?
*Note I have also tried using Meteor's Accounts.onCreateUser(function(options, user) but facing the same issue.
[...] there is no $push operation for mongo [...]
Sure, there is a $push operator, which appends a specified value to an array.
However, I think what you are trying to do is to update a document and keep all values which are already set.
Here is how you can do that:
Query the document first to get the object you want to set.
Update the respective object.
Run the MongoDB update operation to set the new object.
For instance:
var user = Meteor.users.findOne({
_id: newUserId
});
var servicesUserData = user.services;
servicesUserData.google.email = "your_new_email#gmail.com";
Meteor.users.update({
_id: newUserId
}, {
$set: {
"services": {
servicesUserData
}
}
});

How do I link each user to their data in Firebase?

I plan to create a main tree named users which will include the name different users used as username. So, from each username will be included their data e.g. Full Name, Address, Phone No.
I want to know how to get each user's data when they log in on their profile.
First of all i suggest you spend some time getting familiar with firebase by reading the Firebase Guide (Link to old Firebase Guide). Everything you need to know to answer your own question is available there. But for simplicity i will put an example here:
Lets start with security, here are the basic firebase rules you need for this example: (source: Understanding Security) (old source: Understanding Security)
{
"rules": {
"users": {
"$user_id": {
".write": "$user_id === auth.uid"
}
}
}
}
I will skip the actual user creation and logging in and focus on the question about storing and retrieving user data.
Storing data: (source: Firebase Authentication) (old source: User Authentication)
// Get a reference to the database service
var database = firebase.database();
// save the user's profile into Firebase so we can list users,
// use them in Security and Firebase Rules, and show profiles
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email
//some more user data
});
}
The resulting firebase data will look like this:
{
"users": {
"simplelogin:213": {
"username": "password",
"email": "bobtony"
},
"twitter:123": {
"username": "twitter",
"email": "Andrew Lee"
},
"facebook:456": {
"username": "facebook",
"email": "James Tamplin"
}
}
}
And last but not least the retreiving of the data, this can be done in several ways but for this example i'm gonna use a simple example from the firebase guide: (source: Read and Write data) (old source: Retreiving Data)
//Get the current userID
var userId = firebase.auth().currentUser.uid;
//Get the user data
return firebase.database().ref('/users/' + userId).once('value').then(function(snapshot) {
//Do something with your user data located in snapshot
});
EDIT: Added example of return data
So when you are logged in as user twitter:123 you will get a reference to the location based on your user id and will get this data:
"twitter:123": {
"username": "twitter",
"email": "Andrew Lee"
}
Though I agree with Andre about setting the rules for good security - I would handle the data a bit differently. Instead of generating the string I use the child() method. It's a matter of personal preference.
Get the UID and define a data object:
let user = firebase.auth().currentUser
let uid = user.uid
let yourdata = { foo: 'something', bar: 'other'}
Save the data:
firebase.database().ref('users').child(uid).set(yourdata)
.then((data) => {
console.log('Saved Data', data)
})
.catch((error) => {
console.log('Storing Error', error)
})
Fetch the data:
firebase.database().ref('users').child(uid).once('value')
.then((data) => {
let fetchedData = data.val()
console.log('Fetched Data', fetchedData)
})
.catch((error) => {
console.log('Fetching Error', error)
})
Please notice that set() will override your data so you might want to use push() later on.

Categories