supergentle
supergentle

Reputation: 1091

Sending images with AngularJS and NodeJS

Hi I am making a service to send images with users' information. For example, name, phone number, and their images to upload.

I am planning to use ng-file-upload, one of AngularJS custom dependency. And then, I am going to use Nodemailer to send all the information and images to somewhere else.

But my question is can I send other text data along with ng-file-upload? And second is can I send images with other text data through nodemailer?

Upvotes: 0

Views: 1511

Answers (2)

jerorx
jerorx

Reputation: 658

Although OP has found a solution in the end, since I had the same problem I figured I'd post the whole code here for others who might struggle with that.

So here is how I combined ng-file-upload and nodemailer to upload and send attachments by e-mail using Gmail:

HTML form:

<form name="postForm" ng-submit="postArt()">
...
<input type="file" ngf-select ng-model="picFile" name="file" ngf-max-size="20MB">
...
</form>

Controller:

app.controller('ArtCtrl', ['$scope', 'Upload', function ($scope, Upload) {
    $scope.postArt = function() {
        var file = $scope.picFile;
        console.log(file);
        file.upload = Upload.upload({
            url: '/api/newart/',
            data: {
                username: $scope.username,
                email: $scope.email,
                comment: $scope.comment,
                file: file
            }
        });
    }
}]);

Server:

var nodemailer = require('nodemailer');
var multipartyMiddleware = require('connect-multiparty')();
// multiparty is required to be able to access req.body.files !

app.mailTransporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: ...
        pass: ...
    },
    tls: { rejectUnauthorized: false } // needed or Gmail might block your mails
});

app.post('/api/newart', multipartyMiddleware,function(req,res){
    console.log(req.files);
    mailOptions = {
        from: req.body.email,
        to: ...,
        subject: ...
        text: ...,
        attachments: [{
            filename: req.files.file.name,
            path: req.files.file.path // 'path' will stream from the corresponding path
        }]
    };
    app.mailTransporter.sendMail(mailOptions, function(err) {
        if (err) {
            console.log(err);
            res.status(500).end();
        }
        console.log('Mail sent successfully');
        res.status(200).end()
    });
});

The nodemailer examples helped me figure this out!

This works for any file type. The key aspect that some people might miss out is that you need multiparty to access the uploaded file (in req.body.files). Then the most convenient way to attach it is using the path key in the attachment object.

Upvotes: 1

Ravi Shankar Bharti
Ravi Shankar Bharti

Reputation: 9268

Definitely you can send images as attachment using nodemailer.

Try this for sending image as an attachment :

var mailOptions = {
    ...
    html: 'Embedded image: <img src="cid:[email protected]"/>',
    attachments: [{
        filename: 'image.png',
        path: '/path/to/file',
        cid: '[email protected]' //same cid value as in the html img src
    }]
}

For more reference on sending image as attachment go through nodemailer's "using Embedded documentation".

For the first part of the question:

Yes! you can send other text data along with image using ng-file-upload. It depends how you want to do it and what you want to achieve.

For example, see the code below:

HTML Template

<form name="form">
    <input type="text" ng-model="name" ng-required="true">
    <input type="text" ng-model="phoneNo" ng-required="true">
    <div class="button" ngf-select ng-model="file" name="file" ngf-pattern="'image/*'" ngf-accept="'image/*'" ngf-max-size="20MB" ngf-min-height="100" ngf-resize="{width: 100, height: 100}">Select</div>
    <button type="submit" ng-click="submit()">submit</button>
</form>

Controller

$scope.submit = function() {
  if ($scope.form.file.$valid && $scope.file) {
    $scope.upload($scope.file);
  }
};

// upload on file select or drop
$scope.upload = function (file) {
    Upload.upload({
        url: 'upload/url',
        data: {file: file, 'name': $scope.name, 'phoneNo' : $scope.phoneNo}
    }).then(function (resp) {
        console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
    }, function (resp) {
        console.log('Error status: ' + resp.status);
    }, function (evt) {
        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
        console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
    });
};

Read ng-file-upload documentation completely to see understand all the things you can do along with file upload. It has many examples to make you understand everything.

I hope it helps, and answer your question.

Upvotes: 1

Related Questions