Why is my SQL data returning undefined in my array methods? - sql

The First array returned when I console log person
The second array that returns when I console log person
I am trying to create a function that pulls the data from 2 tables in my SQL database. I am using async/await, which is still new to me. The issue is somewhere in the two array methods; for some reason they are returning data as undefined.
async function updateRole() {
console.log('hi');
//cycle through both arrays and create new arrays with same information using maps
//return object with employee and role info
const allEmployees = await db.promise().query(`SELECT * FROM employees`);
const allRoles = await db.promise().query(`SELECT * FROM roles`);
console.log(allEmployees);
const employeeChoices = allEmployees.map((person) => {
return {
name: `${person.first_name} ${person.last_name}`,
value: person.id
}
})
const roleChoices = allRoles.map((role) => {
return {
name: role.title,
value: role.id
}
})
const { employeeId, roleId } = await inquirer.prompt([
{
type: 'list',
name: 'employeeId',
message: 'Which employee would you like to update?',
choices: employeeChoices
},
{
type: 'list',
name: 'roleId',
message: 'What is their new role?',
choices: roleChoices
}])
await db.promise().query(`UPDATE employees SET role_id = ? WHERE id = ?`, [roleId, employeeId])
console.log('Successfully updated employee!');
askQuestions();
Update: I added screenshots fo the console log for person. role returns the same format, but obviously different data. I am unsure what the array of ColumnDefinition objects does, or why it's there.

Related

TypeORM select data from nested relations

Using
await this.budgetRepository.createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.getMany();
I get a list with objects like this:
Budget {
id: 1,
unnecessary_property1: something,
contact: Contact {
unnecessary_property2: something,
photo: Photo {
unnecessary_property3: something,
url: "url.com"
},
},
}
But I want to select only the necessary properties in the nested objects (relations) and get a list of objects like this:
Budget {
id: 1,
contact: Contact {
photo: Photo {
url: "url.com"
},
},
}
How is that possible with TypeORM?
This is possible but we have to select everything manually with .select()
await this.budgetRepository.createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.select(['budget.id', 'contactPhoto.url']
.getMany();
If you're using repository pattern that you will be achieve the similar result with:
await this.budgetRepository.find({
relations: ["contact", "contact.photo"]
})
You would have to use the .select() function and pass the given properties you want for each entity.
for your example:
const user = await createQueryBuilder("budget")
.leftJoinAndSelect("budget.contact", "contact")
.leftJoinAndSelect("contact.photo", "contactPhoto")
.select([/* everything from budget */, 'contact.photo.url'....]) // added selection
.getMany();

Prisma how can I update only some of the models fields in update()

I have a Prisma model with lets say 10 fields.
Think User model with firstname, lastname, address, e-mail , phone, mobile, age etc.
I am trying to write a update method for this, where I most of the times only want to update some or only 1 of the fields. Not the whole User. If the field is not sent with the request, I want to keep the value from the db.
What would the best practice be for this. Should I check for all fields to be in the req object?
How could I write this for prisma?
Example on how I would like it to work:
req = {firstname: 'Bob', email: 'bob#bob.bob', etc}
const updateUser = await prisma.user.update({
where: {
email: 'viola#prisma.io',
},
data: {
req.firstname ? (email: req.firstname) : null,
req.email ? (email: req.email) : null,
req.address? (email: req.address) : null,
},
})
Or should I check for values to be present in req and build the data object in 10 versions:
let customDataObject = {}
if (req.firstname) {
customDataObject.firstname = req.firstname
}
if (req.email) {
customDataObject.email= req.email
}
const updateUser = await prisma.user.update({
where: {
email: 'viola#prisma.io',
},
data: customDataObject,
})
The undefined property is used in Prisma to do exactly what you're trying to achieve. Basically, when a field is assigned undefined it means ignore this and do nothing for this field. You can learn more about this in the article about null and undefined in the docs.
This is what your update query should look like.
// assuming email, firstname and address fields exist in your prisma schema.
const updateUser = await prisma.user.update({
where: {
email: 'viola#prisma.io',
},
data: {
firstname: req.firstname || undefined, // if req.firstname is falsy, then return undefined, otherwise return it's value.
email: req.email || undefined,
address: req.address || undefined
},
})

How to compare results of two vuejs computed properties

Our application has events that users can apply to, as well as blog posts written about different events. We want to show users all of the blog posts for events where they have applied.
Each post has an eventId and each application object contains event.id. We want to show all of the posts where the the eventId is equal to one of the application.event.id's.
Here are our computed properties...
computed: {
...mapState(['posts', 'currentUser', 'applications']),
myApplications: function() {
return this.applications.filter((application) => {
return application.user.id === this.currentUser.uid
})
},
myEventPosts: function() {
return this.posts.filter((post => {
post.eventId.includes(this.myApplications.event.id)
})
}
How can we change meEventPosts to get the show the correct results?
Thanks!
This question is mostly related to JS, not Vue and calculated properties. It will be better if you create such a code snippet the next time, as I did below.
const posts = [{eventId: 1, name: 'Post 1'}, {eventId: 2, name: 'Post 2'}, {eventId: 3, name: 'Post 3'}];
const myApplications = [{eventId: 2, name: 'App 2'}];
const myEventPosts = function () {
const eventsIds = myApplications.map((app) => app.eventId);
return posts.filter((post) => eventsIds.includes(post.eventId));
}
console.log('posts:', myEventPosts());
So your myEventPosts computed property should look like:
myEventPosts: function() {
const eventsIds = this.myApplications.map((app) => app.eventId);
return this.posts.filter((post) => eventsIds.includes(post.eventId));
}

Facing some issue to print the API response values in one sentence

I am trying to assert and print the response, for that need help.
Below is response body:
{
"createdIncidents":[
{
"incidentRef":"I0000000",
"personName":"API API",
"personType":"Patient"
},
{
"incidentRef":"I0000000",
"personName":"Ballarat HelpDesk",
"personType":"Staff"
},
{
"incidentRef":"I0000000",
"personName":"test api",
"personType":"Visitor"
},
{
"incidentRef":"I0000000",
"personName":null,
"personType":"Hazard"
}
]
}
I am trying to print incidentRef and personType together in a string.
For that, I am using this code:
var data = JSON.parse(responseBody);
data.createdIncidents.forEach(function(incident, personT) {
var personType = "personType" + personT.personType;
var incidents = "incidentRef" + incident.incidentRef;
var pt = tests["incidents created for " + personType ] = 'personType';
var inc = tests["incidents number is " + incidents] = 'incidents';
tests["incidents created for" +inc && + pt ];
});
Here it is not reading the second items inside the function.
In a separate function declaration it works fine.
I want to print it as:
"incidentRef": "I0000000 is created for "personType": "Hazard""
This would log each item from the createdIncidents array to the console - Unsure what you're actually trying to assert against though:
_.each(pm.response.json().createdIncidents, (arrItem) => {
console.log(`Incident Ref: ${arrItem.incidentRef} is created for Person Type: ${arrItem.personType}`)
})
Given your response data, this would be the output:
Incident Ref: I0000000 is created for Person Type: Patient
Incident Ref: I0000000 is created for Person Type: Staff
Incident Ref: I0000000 is created for Person Type: Visitor
Incident Ref: I0000000 is created for Person Type: Hazard
This could be wrapped in a pm.test() and the different items can be asserted against using the pm.expect() syntax.
This is very basic and is very hardcoded but it would check the data in your example:
pm.test('Check the response', () => {
_.each(pm.response.json().createdIncidents, (arrItem) => {
pm.expect(arrItem.incidentRef).to.equal("I0000000")
pm.expect(arrItem.personType).to.be.oneOf(['Patient','Staff','Visitor','Hazard'])
console.log(`Incident Ref: ${arrItem.incidentRef} is created for Person Type: ${arrItem.personType}`)
})
})

How to omit fields when serializing Mongoose models in MEAN [duplicate]

I have the following simple shema:
var userSchema = new Schema({
name : String,
age: Number,
_creator: Schema.ObjectId
});
var User = mongoose.model('User',userSchema);
What I want to do is create the new document and return to client, but I want to exclude the 'creator' field from one:
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
res.json(200, {user: user}); // how to exclude the _creator field?
});
});
At the end I want to send the new created user without _creator field:
{
name: 'John',
age: 45
}
Is it possible to make without extra find request to mongoose?
P.S:It's preferable to make it by
Another way to handle this on the schema level is to override toJSON for the model.
UserSchema.methods.toJSON = function() {
var obj = this.toObject()
delete obj.passwordHash
return obj
}
I came across this question looking for a way to exclude password hash from the json i served to the client, and select: false broke my verifyPassword function because it didn't retrieve the value from the database at all.
The documented way is
UserSchema.set('toJSON', {
transform: function(doc, ret, options) {
delete ret.password;
return ret;
}
});
UPDATE - You might want to use a white list:
UserSchema.set('toJSON', {
transform: function(doc, ret, options) {
var retJson = {
email: ret.email,
registered: ret.registered,
modified: ret.modified
};
return retJson;
}
});
Come across your question when I was trying to find a similar answer with pymongo. It turns out that in mongo shell, with the find() function call, you can pass a second parameter which specifies how the result document looks like. When you pass a dictionary with attribute's value being 0, you are excluding this field in all the document that come out of this query.
In your case, for example, the query will be like:
db.user.find({an_attr: a_value}, {_creator: 0});
It will exclude _creator parameter for you.
In pymongo, the find() function is pretty much the same. Not sure how it translate to mongoose though. I think it's a better solution compare to manually delete the fields afterwards.
Hope it helps.
I would use the lodash utilities .pick() or .omit()
var _ = require('lodash');
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
// Only get name and age properties
var userFiltered = _.pick(user.toObject(), ['name', 'age']);
res.json(200, {user: user});
});
});
The other example would be:
var _ = require('lodash');
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
// Remove _creator property
var userFiltered = _.omit(user.toObject(), ['_creator']);
res.json(200, {user: user});
});
});
You can call toObject() on the document to convert it to a plain JS object that you can freely modify:
user = user.toObject();
delete user._creator;
res.json(200, {user: user});
By following the MongoDB documentation, you can exclude fields by passing a second parameter to your query like:
User.find({_id: req.user.id}, {password: 0})
.then(users => {
res.status(STATUS_OK).json(users);
})
.catch(error => res.status(STATUS_NOT_FOUND).json({error: error}));
In this case, password will be excluded from the query.
font: https://docs.mongodb.com/v2.8/tutorial/project-fields-from-query-results/#return-all-but-the-excluded-field
I am using Mongoosemask and am very happy with it.
It does support hiding and exposing properties with other names based on your need
https://github.com/mccormicka/mongoosemask
var maskedModel = mongomask.mask(model, ['name', 'age']); //And you are done.
You can do this on the schema file itself.
// user.js
var userSchema = new Schema({
name : String,
age: Number,
_creator: Schema.ObjectId
});
userSchema.statics.toClientObject = function (user) {
const userObject = user?.toObject();
// Include fields that you want to send
const clientObject = {
name: userObject.name,
age: userObject.age,
};
return clientObject;
};
var User = mongoose.model('User',userSchema);
Now, in the controller method where you are responding back to the client, do the following
return res.json({
user: User.toClientObject(YOUR_ENTIRE_USER_DOC),
});