Sequelize how to transform objects list - node.js

I have this code
employees = []
async function fillEmployeesList() {
await Employe.findAll().then(allEmployes => {
employees = allEmployes;
console.log('All employees: ' + allEmployes[0].nom);
});
}
And I want to transform the raw object to correct employee object, how can I do this? Because allEmployes is currently a list of sequelize object, I want it to be a list of Employee object, how? (Sorry english is not my first language)

you can try this
employees = []
async function fillEmployeesList() {
const allEmployees = await Employe.findAll();
employees = allEmployees.map(employee => {
return employee.toJSON();
});
}
im adding just this return employee.toJSON(); line of code.

If you are looking to assign employees data directly to a variable without using callback and manipulate those data as per your requirements you can do like this.
employees = []
async function fillEmployeesList() {
const allEmployees = await Employe.findAll();
employees = allEmployees.map(employee => {
return {"nom", employee.nom, "other_key": employee.name};
})
console.log(employees);//will print employees modified data
}

You can try this
employees = []
async function fillEmployeesList() {
await Employe.findAll({raw: true}).then(allEmployes => {
employees = allEmployes;
console.log('All employees: ' + allEmployes[0].nom);
});
}

If you only need the raw data and don't want to update anything, you can do like this to get the raw data.
employees = []
async function fillEmployeesList() {
await Employe.findAll({raw: true}).then(allEmployes => {
employees = allEmployes;
console.log('All employees: ' + allEmployes[0].nom);
});
}
You can read about it here. http://docs.sequelizejs.com/manual/models-usage.html#raw-queries

Related

Google Firestore array_contains query doesn't work

I am trying to run a simple query to find other document that contains some ID. Here is how it looks, and here is what I am trying to get. I don't see a reason for it to work this way. I tried this code for Firestore Functions but it doesn't work.
I tried this code:
exports.updateDietDaysWhenMealChanges = functions.firestore
.document("Posilek/{posilekId}")
.onUpdate((change, context) => {
const posilekId = context.params.posilekId;
const posilekAfter = change.after.data();
return db.collection("DietDays")
.where("Meals", "array-contains", { ID: posilekId })
.get()
.then(snapshot => {
if (snapshot.empty) {
functions.logger.log("No matching DietDay found");
return null;
} else {
return Promise.all(snapshot.docs.map(dietDayDoc => {
const dietDayId = dietDayDoc.id;
const meals = dietDayDoc.data().Meals;
const mealIndex = meals.findIndex(meal => meal.ID === posilekId);
meals[mealIndex] = { ID: posilekId, Portions: posilekAfter.Portions };
functions.logger.log(`Editing meal in DietDay with ID: ${dietDayId}`);
return dietDayDoc.ref.update({ Meals: meals });
}));
}
});
});
And I tried manual query.
The array-contains operator can only check for exact matches between items in the array and the value you pass. So in code:
.where("Meals", "array-contains", { ID: posilekId, Portions: 12.5 })
There is no way to do a partial match.
The common workaround is to add an additional field (e.g. MealIDs) that contains just the value you want to filter on:
MealIDs: ["ohN....", "..."]
With that additional array, you can then filter with:
.where("MealIDs", "array-contains", posilekId)

how to get a list of database in quick.db?

I want to get a list of a key inside my database I use db.set(`fuel_${car}`, amount of fuel) and then I want to get a list of all cars fuel, here is my code :
/*set the fuel of lol9*/
client.on('message', async message => {
if(message.content === 'db') {
const m = await db.get('fuel');
message.channel.send(`${m}`);
}
})
The quick.db documentation states:
.all() -> array
This function returns the entire active table as an array.
await db.all()
// -> [Array]
This being said, you could do this:
let carFuelArray = [];
await db.all().then(array => {
array.forEach(element, => {
if(element.startWith("fuel_")) {
// if you want to log "fuel_{car}"
carFuelArray.push(element)
// if you want to log the "fuel_{car}" key value
carFuelArray.push(db.get(element))
}
})
})

Get all documents in collection using Cloud Firestore

I read several documentation but I don't understand why I should use an extra layer(foreach) in my code when I read all of the data inside a collection using Firebase (Cloud Firestore).
Here is the original documentation:
https://firebase.google.com/docs/firestore/query-data/get-data#get_all_documents_in_a_collection
Here is my code:
async loadUsers(): Promise<User[]> {
const users = new Array<User>();
const snapshot = await this.firestore.collection('users').get();
snapshot.forEach((collection) => {
collection.docs.forEach(doc => {
users.push(doc.data() as User);
});
});
return users;
}
As I understand it should work like this:
async loadUsers(): Promise<User[]> {
const users = new Array<User>();
const snapshot = await this.firestore.collection('users').get();
snapshot.forEach(doc => {
users.push(doc.data() as User);
});
return users;
}
Error message:
"Property 'data' does not exist on type 'QuerySnapshot'."
.collection().get() does NOT return an array; it returns a QuerySnapshot, which has a property .docs, which is an array of QueryDocumentSnapshot, each of which has a property .data, which is the data read from the document.
Documentation
https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference
In new modular firebase firestore(version 9.+) it should be like this:
import { getFirestore, collection, query, getDocs } from 'firebase/firestore/lite'
async readAll() {
const firestore = getFirestore()
const collectionRef = collection(firestore, '/users')
let q = query(collectionRef, orderBy('createTimestamp', 'desc'))
const querySnapshot = await getDocs(q)
const items = []
querySnapshot.forEach(document => {
items.push(document.data())
})
return items
}
I could not find any parameter on querySnapshot directly that is something like .docs was and included whole array before. So it is kinda like onSnapshot is and was.
Based on #LeadDreamer answer, I could manage to simplify the code
async loadUsers(): Promise<User[]> {
const users = new Array<User>();
await this.firestore.collection('users').get().subscribe(querySnapshot => {
querySnapshot.docs.forEach(doc => {
users.push(doc.data() as User);
});
});
return users;
}
There seems to be no other way but to iterate.
const q = query(collection(db, "item"));
getDocs(q).then( response => {
const result = response.docs.map(doc=>({
id: doc.id,
...doc.data(),
}))
console.log(result);
}).catch(err=>console.log(err))

How to convert the auth response into array of objects?

I am trying to get the response of the users using auth function and i have to create an excel sheet using the xlsx-populate library and i am able to convert that into an array of objects as the limit is 1000 so there are multiple arrays of objects. and i am not able to figure out how can i do this problem.in this problem, i am simply fetching results using auth and try to get the results into an array of objects. and i am also tried to use the objects to pass into the excel sheet but it gives the excel sheet with last 1000 queries response
const admin = require("firebase-admin");
const momentTz = require("moment-timezone");
const XlsxPopulate = require("xlsx-populate");
momentTz.suppressDeprecationWarnings = true;
const {
alphabetsArray
} = require("./constant");
var start = momentTz().subtract(4, "days").startOf("day").format();
var start = momentTz(start).valueOf();
const end = momentTz().subtract(1, "days").endOf("day").format();
const listAllUsers = async(nextPageToken) =>{
const [workbook] = await Promise.all([
XlsxPopulate.fromBlankAsync()
]);
const reportSheet = workbook.addSheet("Signup Report");
workbook.deleteSheet("Sheet1");
reportSheet.row(1).style("bold", true);
[
"Date",
"TIME",
"Phone Number"
].forEach((field, index) => {
reportSheet.cell(`${alphabetsArray[index]}1`).value(field);
});
let count = 0
// List batch of users, 1000 at a time.
const data = [];
admin
.auth()
.listUsers(1000, nextPageToken)
.then (async (listUsersResult) => {
listUsersResult.users.forEach((userRecord) =>{
const time = userRecord.metadata.creationTime;
const timestamp = momentTz(time).valueOf();
// console.log(timestamp)
if (timestamp >= 1585704530967 ) {
console.log(time);
let column = count+2;
count++;
data.push(userRecord.toJSON())
reportSheet.cell(`A${column}`).value(time);
reportSheet.cell(`C${column}`).value(userRecord.phoneNumber);
}
});
console.log(JSON.stringify(data))//this is the array of the object and i am getting after 1000 response
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
await workbook.toFileAsync("./SignUp.xlsx");
}
})
// .catch(function (error) {
// console.log("Error listing users:", error);
// });
// const datas = []
// datas.push(data)
// console.log(datas)
return ;
}
// Start listing users from the beginning, 1000 at a time.
listAllUsers();
and the output i am getting is like this
[]
[]
[]
[]
[]
i want to convert this into a single array of response
You have a race condition. When you perform your console.log(JSON.stringify(data)) your listUserQuery is in progress (and in async mode) and you don't have yet the answer when you print the array. Thus the array is empty.
Try this (I'm not sure of this optimal solution, I'm not a nodeJS dev)
admin
.auth()
.listUsers(1000, nextPageToken)
.then (async (listUsersResult) => {
listUsersResult.users.forEach((userRecord) =>{
const time = userRecord.metadata.creationTime;
const timestamp = momentTz(time).valueOf();
// console.log(timestamp)
if (timestamp >= 1585704530967 ) {
console.log(time);
let column = count+2;
count++;
data.push(userRecord.toJSON())
reportSheet.cell(`A${column}`).value(time);
reportSheet.cell(`C${column}`).value(userRecord.phoneNumber);
}
}
console.log(JSON.stringify(data))//this is the array of the object and i am getting after 1000 response
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
await workbook.toFileAsync("./SignUp.xlsx");
}
);

Using node.js and graphql - I'm trying to display the total number of students for each school, but by Promise.all(), it returns empty

async studentCount(#Parent() school: School): Promise<number> {
let studentIds = []
let cohortStudentIds = []
// find all the programs for each school
const programs = await this.programService.find({ schoolId: school.id })
// find all the cohorts for each program
programs.map(async program => {
//collect the student ids per cohort within array
const cohortsWithStudents = await this.cohortService.getStudentsForCohortsByProgramId(program.id)
// find all the students by looping through each cohort and save in cohortStudentIds[]
cohortsWithStudents.map(async (cohort) => {
await cohort.students.map(async (student) => { await cohortStudentIds.push(student.id) })
});
//collect all the student id arrays into 1 big array
studentIds = await [
...studentIds,
...cohortStudentIds
]
})
await Promise.all([programs, cohortStudentIds, studentIds])
.then((values) => {
console.log( values )
return values
});
console.log('xxx')
// return the number of students per school
return uniq(studentIds).length
}
You're passing an async function as the callback to map(), which results in an array of promises, but you're never waiting for those.
In contrast, you're awaiting a lot of things you don't need to wait for as they are not promises, like the return value of push, the return value of map, or the array literal.
You should write something like
async studentCount(#Parent() school: School): Promise<number> {
let studentIds = new Set
const programs = await this.programService.find({ schoolId: school.id })
await Promise.all(programs.map(async program => {
// ^^^^^^^^^^^^^^^^^
const cohortsWithStudents = await this.cohortService.getStudentsForCohortsByProgramId(program.id)
for (const cohort of cohortsWithStudents) {
for (const student of cohort.students) {
studentIds.add(student.id)
}
}
});
return studentIds.size
}

Resources