Save() won't save all data (Mongoose)

ghz 8months ago ⋅ 95 views

So here's my issue: I'm guessing it's a asynchronous problem but the save() method saves only three properties (with values) of all documents:

fetch("***")
    .then(response => response.json())
    .then(data => {

    for (const fruit of data) {
        let name = fruit.name;
        let id = fruit.id;
        let family = fruit.family;
        let order = fruit.order;
        let genus = fruit.genus;
        let calories = fruit.nutritions.calories;
        let fat = fruit.nutritions.fat;
        let sugar = fruit.nutritions.sugar;
        let carbohydrates = fruit.nutritions.carbohydrates;
        let protein = fruit.nutritions.protein;

        let newFruit = new db({
            name: name,
            id: id,
            family: family,
            order: order,
            genus: genus,
            nutritions: { calories: calories, fat: fat, sugar: sugar, carbohydrates: carbohydrates, protein: protein }
        })
    
       newFruit.save()
    }
});

I've tried to make an asynchronous function and make it synchronous with await in it. Like so:

fetch("***")
    .then(response => response.json())
    .then(data => {

    async function saveFruits (){

    for (const fruit of data) {
        let name = fruit.name;
        let id = fruit.id;
        let family = fruit.family;
        let order = fruit.order;
        let genus = fruit.genus;
        let calories = fruit.nutritions.calories;
        let fat = fruit.nutritions.fat;
        let sugar = fruit.nutritions.sugar;
        let carbohydrates = fruit.nutritions.carbohydrates;
        let protein = fruit.nutritions.protein;

        let newFruit = new db({
            name: name,
            id: id,
            family: family,
            order: order,
            genus: genus,
            nutritions: { calories: calories, fat: fat, sugar: sugar, carbohydrates: carbohydrates, protein: protein }
        })

        await newFruit.save()
    }}
});

Doesn't work;

EDIT: For the last comment sorry i'll adjust that in the future. I've managed to make it work. It's an exercise for school so i had a setup.js file as so :

    const mongoose = require('mongoose');
    const connectionString = require('../connection');
    
    mongoose.connect(connectionString, { connectTimeoutMS: 2000 })
      .then(() => console.log('Database connected'))
      .catch(error => console.error(error));
    
    const fruitSchema = mongoose.Schema({
        name: String,
        family: String,
        carbohydrates : Number,
        protein: Number,
        fat: Number,
        calories: Number,
        sugar: Number,
    });
    
    const Fruit = mongoose.model('fruits', fruitSchema);
    
    module.exports = Fruit;

So i changed the newFruit variable with the right schema. I still created it using new db.

Answers

It seems like you're facing an issue with the asynchronous nature of the save() method in Mongoose. Your attempt to use an asynchronous function and await inside the loop is a step in the right direction, but it needs to be handled properly to ensure that all save() operations are completed before moving to the next iteration.

Here's how you can modify your code to handle the asynchronous save() calls properly:

fetch("***")
    .then(response => response.json())
    .then(async data => {
        for (const fruit of data) {
            let name = fruit.name;
            let id = fruit.id;
            let family = fruit.family;
            let order = fruit.order;
            let genus = fruit.genus;
            let calories = fruit.nutritions.calories;
            let fat = fruit.nutritions.fat;
            let sugar = fruit.nutritions.sugar;
            let carbohydrates = fruit.nutritions.carbohydrates;
            let protein = fruit.nutritions.protein;

            let newFruit = new db({
                name: name,
                id: id,
                family: family,
                order: order,
                genus: genus,
                nutritions: { calories: calories, fat: fat, sugar: sugar, carbohydrates: carbohydrates, protein: protein }
            });

            try {
                await newFruit.save();
                console.log(`Fruit ${name} saved successfully`);
            } catch (error) {
                console.error(`Error saving fruit ${name}: ${error}`);
            }
        }
    });

In this modified version:

  • The save() operation for each fruit is wrapped inside a try-catch block to handle any potential errors during the save process.
  • The await keyword is used inside the loop to ensure that each save() operation completes before moving to the next iteration.

By using await inside the loop and properly handling errors, you ensure that all save() operations are completed sequentially and any errors are appropriately handled.