I'm trying to collection queries in the while loop. But I'm getting a "Query was already executed" error. How can I do that? I have a custom field and I need to make sure it is unique. I also need to use this function elsewhere.
async function createRandomID() {
let id = Math.random().toString(36).slice(2, 6).toUpperCase();
let unique = false;
while (!unique) {
await Deed.findOne({ deedId: id }, async (err, doc) => {
if (!doc) {
unique = true;
}
else {
id = Math.random().toString(36).slice(2, 6).toUpperCase();
}
})
}
return id;
}
const addNewDeed = asyncErrorWrapper(async (req, res, next) => {
let information = req.body;
const deedId = await createRandomID();
/*Other Operations...*/
});
I try to use redux toolkit and I have this as menu-slice.js
I try to use property accessors to add a new property to fileItems, its initial value is an empty object.
import { createSlice } from "#reduxjs/toolkit";
const menuSlice = createSlice({
name: "ui",
initialState: {
fileItems: {},
},
reducers: {
setFileDate: (state, action) => {
state.FileDate = action.payload;
},
replaceFileItems: (state, action) => {
const filesList = action.payload.map((fileName) =>
fileName.slice(fileName.indexOf("/") + 1)
);
state.fileItems[state.FileDate] = filesList;
console.log(`filesList: ${filesList}`);
console.log(`state.fileItems: ${JSON.stringify(state.fileItems)}`);
console.log(`state.FileDate: ${state.FileDate}`);
state.fileContents = null;
},
I call dispatch with the api return value ( dispatch(menuActions.replaceFileItems(fileResponse.data));)
in menu-action.js:
the return value is an array of strings.
export const fetchFiles = (fileDate) => {
return async (dispatch) => {
const fetchFilesList = async () => {
const response = await fetch(
"some url" +
new URLSearchParams({
env: "https://env.com",
date: fileDate,
})
);
if (!response.ok) {
throw new Error("Fail to fetch files list!");
}
const data = await response.json();
return data;
};
try {
const fileResponse = await fetchFilesList();
dispatch(menuActions.setFileDate(FileDate));
dispatch(menuActions.replaceFileItems(fileResponse.data));
} catch (error) {
dispatch(
menuActions.showNotification({....
})
);
}
};
};
But it never prints console logs and didn't display where went wrong in the console or in the chrome redux extension.
I want to add data into state.fileItems on each click that triggers fetchFiles() when it returns a new array:
from state.fileItems = {}
check if state.fileItems already has the date as key,
if not already has the date as key,
change to ex: state.fileItems = {"2022-01-01": Array(2)}
and so on..
ex: state.fileItems = { "2022-01-01": Array(2), "2022-01-02": Array(2) }
I also tried to set state.fileItems as an empty array, and use push, but it didn't work either, nothing printed out, state.fileItems value was always undefined.
Can anyone please tell me why this didn't work?
Thanks for your time to read my question.
Hi I am working in a NestJS project using mongodb and mongoose.
I have to create transactions with a lot of promises inside, so i think it was a good idea to use Promise.all() inside my transaction for performace issues.
Unfortunately when i started working with my transactions i have a first issue, i was using
session.startTransaction(); and my code was throwing the following error:
Given transaction number 2 does not match any in-progress transactions. The active transaction number is 1, the error was thrown sometimes, not always but it was a problem
So i read the following question Mongoose `Promise.all()` Transaction Error, and i started to use withTransaction(), this solved the problem, but now mi code does not work propertly.
the code basically takes an array of bookings and then creates them, also needs to create combos of the bookings, what I need is that if a creation of a booking or a combo fail nothing should be inserted, for perfomance I use Promise.all().
But when i execute the function sometimes it creates more bookings than expected, if bookingsArray is from size 2, some times it creates 3 bookings and i just don't know why, this occurs very rarely but it is a big issue.
If i remove the Promise.all() from the transaction it works perfectly, but without Promise.all() the query is slow, so I wanted to know if there is any error in my code, or if you just cannot use Promise.all() inside a mongodb transaction in Nestjs
Main function with the transaction and Promise.all(), this one sometimes create the wrong number of bookings
async createMultipleBookings(
userId: string,
bookingsArray: CreateBookingDto[],
): Promise<void> {
const session = await this.connection.startSession();
await session.withTransaction(async () => {
const promiseArray = [];
for (let i = 0; i < bookingsArray.length; i++) {
promiseArray.push(
this.bookingRepository.createSingleBooking(
userId,
bookingsArray[i],
session,
),
);
}
promiseArray.push(
this.bookingRepository.createCombosBookings(bookingsArray, session),
);
await Promise.all(promiseArray);
});
session.endSession();
}
Main function with the transaction and withot Promise.all(), works fine but slow
async createMultipleBookings(
userId: string,
bookingsArray: CreateBookingDto[],
): Promise<void> {
const session = await this.connection.startSession();
await session.withTransaction(async () => {
for (let i = 0; i < bookingsArray.length; i++) {
await this.bookingRepository.createSingleBooking(
userId,
bookingsArray[i],
session,
);
}
await this.bookingRepository.createCombosBookings(bookingsArray, session);
});
session.endSession();
}
Functions called inside the main function
async createSingleBooking(
userId: string,
createBookingDto: CreateBookingDto,
session: mongoose.ClientSession | null = null,
) {
const product = await this.productsService.getProductById(
createBookingDto.productId,
session,
);
const user = await this.authService.getUserByIdcustomAttributes(
userId,
['profile', 'name'],
session,
);
const laboratory = await this.laboratoryService.getLaboratoryById(
product.laboratoryId,
session,
);
if (product.state !== State.published)
throw new BadRequestException(
`product ${createBookingDto.productId} is not published`,
);
const bookingTracking = this.createBookingTraking();
const value = product.prices.find(
(price) => price.user === user.profile.role,
);
const bookingPrice: Price = !value
? {
user: user.profile.role,
measure: Measure.valorACotizar,
price: null,
}
: value;
await new this.model({
...createBookingDto,
userId,
canceled: false,
productType: product.productType,
bookingTracking,
bookingPrice,
laboratoryId: product.laboratoryId,
userName: user.name,
productName: product.name,
laboratoryName: laboratory.name,
facultyName: laboratory.faculty,
createdAt: new Date(),
}).save({ session });
await this.productsService.updateProductOutstanding(
createBookingDto.productId,
session,
);
}
async createCombosBookings(
bookingsArray: CreateBookingDto[],
session: mongoose.ClientSession,
): Promise<void> {
const promiseArray = [];
for (let i = 1; i < bookingsArray.length; i++) {
promiseArray.push(
this.combosService.createCombo(
{
productId1: bookingsArray[0].productId,
productId2: bookingsArray[i].productId,
},
session,
),
);
}
await Promise.all(promiseArray);
}
also this is how i create the connection element:
export class BookingService {
constructor(
#InjectModel(Booking.name) private readonly model: Model<BookingDocument>,
private readonly authService: AuthService,
private readonly bookingRepository: BookingRepository,
#InjectConnection()
private readonly connection: mongoose.Connection,
) {}
I have a problem with Vue3+service worker+keep-alive.
I use keep-live in template
<q-page-container>
<router-view v-slot="{ Component }">
<keep-alive :include="['WorkPage']">
<component :is="Component" :key="$route.fullPath"/>
</keep-alive>
</router-view>
</q-page-container>
create queue
createWorkQueue = new Queue('createWorkQueue', {
onSync: async ( {queue} ) => {
let entry
while (entry = await queue.shiftRequest()) {
try {
await fetch(entry.request);
const channel = new BroadcastChannel('sw-messages-work');
channel.postMessage({msg: 'offline-work-uploaded'});
} catch (error) {
await queue.unshiftRequest(entry);
throw error;
}
}
}
})
addEventListener('fetch'
self.addEventListener('fetch', (event) => {
if (event.request.url.endsWith('/api/ins_new_work')) {
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone())
return response
} catch (error) {
await createWorkQueue.pushRequest({request: event.request})
return error
}
}
event.respondWith(bgSyncLogic())
}
})
when in offline I send form - createWorkQueue.pushRequest hangs to 5 minutes
if I delete from keep-alive - WorkPage - then pushRequest works well
but I need keep-alive page. How can I solve this?
I found!!
I use IndexedDB library and for show offline message I read from DB information
const db = await openDB('workbox-background-sync')
but in first time - table 'requests' don't create
I insert next code
const db = await openDB('workbox-background-sync', undefined, { upgrade(db) { db.createObjectStore('requests') }})
and works well
For some reason, the function .save() isn't saving my documents on MongoDB. All seem right and the first two registers work and update successfully, but my third register 'specialBanner' doesn't work.
When I console log service it doesn't show as part of the special object, although when I console special.specialBanner it is there.
Has anyone experienced something like this before?
Thanks for your help :)
const updateSpecial = async (req, res, next) => {
const { title, description, specialBanner } = req.body;
let special;
try {
special = await Special.findById(specialId);
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
if (title) {
special.title = title;
}
if (description) {
special.description = description;
}
if (specialBanner) {
special.specialBanner = specialBanner;
}
try {
//Here if I check 'special I get all the right inputs, but the 'specialBanner'.
special = await special.save();
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
res.status(200).json({ special: special.toObject({ getters: true }) });
};
I assume you are using mongoose and, Special is a collection.
Replace the line
special = await Special.findById(specialId)
with
special = await Special.findById(specialId).exec()