I have created a simple script to fetch Strava activities and save them to a mongoDB, but I ran into the following problem:
My database connections gets disconnected before the activities can be fetched and commited. The following code outputs:
const stravaApi = require('strava-v3');
const mongoose = require('mongoose');
const Activity = require('./models/Activity');
mongoose.connect(process.env.DB_CONNECTION, () => console.log('connected to DB'))
strava = new stravaApi.client(accessToken)
strava.athlete.listActivities({per_page: 2})
.then(payload => {
let activities = []
for (let strava_activity of payload) {
const activity = new Activity({
activityId: strava_activity['id'],
name: strava_activity['name'],
date: strava_activity['start_date'],
type: strava_activity['type'],
distance: strava_activity['distance']
})
activity.save()
.then(data => {
console.log(`Activity from date ${strava_activity['start_date']} saved to DB`);
})
.catch(err => {
console.log(err)
})
}
})
.then(() => {
console.log('Start disconnect')
mongoose.disconnect().then(() => {
console.log("DB disconnected successfully")
})
})
.catch(err => {
console.log(err)
})
Output
connected to DB
DB disconnected successfully
(Error message)
(Error message)
CodePudding user response:
the then
-callback in which the for
loop runs does not return a promise, and so the then
-callback that is chained to it, will kick in in the next microtask.
The promises inside that for
loop should be building towards a promise that the then
-callback would return, but instead the promises returned by activity.save().then(...)
are ignored.
Things become easier when you use async
await
syntax:
(async function () {
await mongoose.connect(process.env.DB_CONNECTION);
console.log('connected to DB');
const strava = new stravaApi.client(accessToken);
const payload = await strava.athlete.listActivities({per_page: 2});
for (const {id, name, start_date, type, distance} of payload) {
const activity = new Activity({
activityId: id,
name,
date: start_date,
type,
distance
});
await activity.save();
console.log(`Activity from date ${start_date} saved to DB`);
}
console.log('Start disconnect')
await mongoose.disconnect();
console.log("DB disconnected successfully");
})().catch(console.log);
CodePudding user response:
Try to pass the DB disconnect only when all instances of the promise are ended, like this:
strava.athlete.listActivities({per_page: 2})
.then(payload => {
let activities = []
for (let strava_activity of payload) {
const activity = new Activity({
activityId: strava_activity['id'],
name: strava_activity['name'],
date: strava_activity['start_date'],
type: strava_activity['type'],
distance: strava_activity['distance']
})
activity.save()
.then(data => {
console.log(`Activity from date ${strava_activity['start_date']} saved to DB`);
})
.catch(err => {
console.log(err)
})
}
})
.then(() => {})
.catch(err => {
console.log(err)
}).finally(() => {
console.log('Start disconnect')
mongoose.disconnect().then(() => {
console.log("DB disconnected successfully")
})
})
In this way they only will disconnect when the consulting is finished