1

I am implementing a web app using MEAN Stack and Angular 6. There I want to submit a form with file upload. '.png' files should be uploaded.

I want to save the file in a different file server and send the url to the image.Currently I upload files into a folder in my project and save the image in db (I used ng2fileupload and multer for that.). Then it saves like this.

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAFUCAYAAABssFR8AAAK..."

But I want to save the image url and the image should be retrived by the url. Does anyone can explain a proper method for that?

Saurabh Mistry
  • 12,833
  • 5
  • 50
  • 71
RMD
  • 311
  • 1
  • 7
  • 22

1 Answers1

0

I faced the same problem a month ago and find out a solution to this problem. Though I haven't used multer in the app.

  1. From my frontend, I will be sending an object to Node API endpoint /event which will look like:-

let img = { content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", filename: 'yourfile.png' }

  1. At the backend, I'm using Cloudinary to store my images (Its free plan allows 10GB storage) and returns secure https URLs. So install it using npm i cloudinary and require in your api.js file. And add the below configuration

    cloudinary.config({ cloud_name: 'yourapp', api_key: 'YOUR_KEY', api_secret: 'YOUR_SECRET_KEY' });

Last Step:- (Not so optimized code)

Let say I have an event Schema which has images array, where I'll be storing the URLs returned by cloudinary.

app.post('/event', (req, res) => {
    try {
        if (req.body.images.length > 0) {

           // Creating new Event instance

            const event = new Event({
                images: [],
            });

           // Looping over every image coming in the request object from frontend
            req.body.images.forEach((img) => {
                const base64Data = img.content.split(',')[1];

            // Writing the images in upload folder for time being 
                fs.writeFileSync(`./uploads/${img.filename}`, base64Data, 'base64', (err) => {
                    if (err) {
                        throw err;
                    }
                });

              /* Now that image is saved in upload folder, Cloudnary picks 
             the image from upload folder and store it at their cloud space.*/
                cloudinary.uploader.upload(`./uploads/${img.filename}`, async (result) => {

                 // Cloudnary returns id & URL of the image which is pushed into the event.images array.
                    event.images.push({
                        id: result.public_id,
                        url: result.secure_url
                    });

                 // Once image is pushed into the array, I'm removing it from my server's upload folder using unlinkSync function
                    fs.unlinkSync(`./uploads/${img.filename}`);

       // When all the images are uploaded then I'm sending back the response
                    if (req.body.images.length === event.images.length) {
                        await event.save();
                        res.send({
                            event,
                            msg: 'Event created successfully'
                        });
                    }
                });
            });
        }
    } catch (e) {
        res.status(400).send(e);
    }
});

P.S. Go ahead and suggest some optimization solution for this code here

Yashwardhan Pauranik
  • 5,370
  • 5
  • 42
  • 65
  • Thanks for your suggestion. I noticed that we can retrieve the file path by multer object. Updated the new question to https://stackoverflow.com/questions/53099208/retrieve-file-path-from-multer-object-and-save-in-mongodb-using-nodejs-and-ang – RMD Nov 01 '18 at 10:19