Search code examples
javascriptnode.jsmongooseasync-awaitcloudinary

waiting the ending loop of promise?


How could I wait for the end of the loop, get the images' paths, and then inject it into the query?

Before data creation:

let images = [];
for ( const file in files ) {
    fs.writeFileSync(  __dirname + '/'+file+'.jpg', files[file].data );
    uploads( __dirname + '/'+file+'.jpg', 'smoothies/recipes' )
        .then( ( resolve ) => {
            images.push('https://res.cloudinary.com/###########' + resolve.public_id) ;
        } )
        .then( () => {
            console.log('images uploaded here path => ', images);
            fs.unlinkSync(  __dirname + '/'+file+'.jpg' );
            console.log('file removed here ');
            //file removed
        })
        .catch( ( error ) => {
            res.status( 500 ).send( {
                message:"failure tu upload the image",
                error,
            } );
        } );
}

Recipe.create( { name, ingredients, steps, images } )
    .then( async () => {
        let recipes = await Recipe.find();
        res.status( 201 ).json( recipes );
    } )
    .catch( ( error ) => {
        res.status( 500 ).send( {
            message:"failure to create the Recipe with images",
            error,
        } );
    } );

I can't find the solution.

Thanks.


Solution

  • You can switch to using await and use the promise versions of the fs functions like this:

    const fsp = fs.promises;
    
    let images = [];
    try {
        for (const file in files) {
            const filename = __dirname + '/' + file + '.jpg';
            await fsp.writeFile(filename, files[file].data);
            let resolve = await uploads(filename, 'smoothies/recipes');
            images.push('https://res.cloudinary.com/###########' + resolve.public_id);
            console.log('images uploaded here path => ', images);
            await fsp.unlink(filename);
            console.log('file removed here ');
        }
    } catch (error) {
        res.status(500).send({
            message: "failure tu upload the image",
            error,
        });
        return;
    }
    
    try {
        await Recipe.create({ name, ingredients, steps, images });
        let recipes = await Recipe.find();
        res.status(201).json(recipes);
    } catch (error) {
        res.status(500).send({
            message: "failure to create the Recipe with images",
            error,
        });
        return;
    }
    

    And, the containing function would need to be tagged as async.