Whenever I try to send an email in Node.js, I encounter 404 errors. Additionally,

I have an Angular application with a form that makes AJAX requests. Emailing works fine, but no matter what I set the response to, I get an error for the path '/send'. I assume Node.js expects the path '/send' to render a template or data, but I just want the path to handle emailing! I use a modal pop-up for the form and Angular UI routing for paths.

app.get('/send', function (req, res, err) { 
  var cartContent = req.body.slice(1,20);
  var content = tableify(cartContent);
  var sendit = {
    to: '*****@gmail.com',
    from: '****@bluenightphoto.com',
    replyTo: req.body[0].email,

    subject: "CP Carpet Quote Request: " + req.body[0].fname + " " + req.body[0].lname , // REQUIRED.

    html: '<b>Customer Quote</b>' + '<br>' + 'Customer Name: ' + req.body[0].fname + " " +
    '<br>' + 'Message: ' + req.body[0].message + '<br>' + <b>Table</b>'+ '<br><br>' + content,
  };

  // Transporter refers to nodemailer and sendit is the login details(mail works fine!)

  transporter.sendMail(sendit, function (req, res, err) {
    if (err) {
      console.log(err + "something strange...");
      res.status(401).send("that's all folks");
    } else {
      res.status(200).send("nothing here");
      console.log("Message sent!");
    }

    transporter.close();
  });
});

Despite successful emailing, my error handler always receives a 404 response.

EDIT: I have tried the two solutions below, but they did not work.

Here is the Angular AJAX code:

var makeForm = function () {
                if (mailJson[1].total !== 0) {
                    deferred.resolve(mailJson);
                    console.log('values loaded successfully again');


                    $http({
                        method : 'GET',
                        url : '/send',
                        data : mailJson,
                        headers : {
                            'Content-type' : 'application/json'
                        }
                    }).success(function () {
                        console.log('success!');
                        $scope.alertEmailOk = true;
                    }).error(function (err) {
                        console.log('there was an error indeed ' + err);
                        $scope.alertEmailOk = false;
                    });
                } else {
                    console.log('no values!');
                    deferred.reject(mailJson);
                }
                return deferred.promise;
            };

The line console.log('there was an error indeed ' + err); always fires...maybe I need to send data back?

Here's the error handler in my Express code:

if (app.get('env') === 'production') {

    // changes it to use the optimized version for production
    app.use('/', express.static(path.join(__dirname, '/dist')));

    // production error handler
    // no stacktraces leaked to user
      app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

Answer №1

// The use of Transporter in reference to nodemailer is essential for sending mail successfully.

After carefully reviewing your comment, let's focus on the following part: From nodemailer

var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9eedfbf0fafbecdef9f3fff7f2b0fdf1f3">[email protected]</a>',
        pass: 'password'
    }
});
var sendIt = { //<------ i've just renamed this compare to nodemailer.com sample 
    from: 'sender@address',
    to: 'receiver@address',
    subject: 'hello',
    text: 'hello world!'
};


// this part is very important !
// note the signature.
transporter.sendMail(sendIt, function(error, info){
    if(error){
        return console.log(error);
    }
    console.log('Message sent: ' + info.response);

});

Now, let's attempt to integrate this into your existing code :

//app.get('/send', function (req, res, err) { 
app.get('/send', function (req, res, next) { 

  var cartContent = req.body.slice(1,20);
  var content = tableify(cartContent);
  var sendit = {
    to: '*****@gmail.com',
    from: '****@bluenightphoto.com',
    replyTo: req.body[0].email,

    subject: "CP Carpet Quote Request: " + req.body[0].fname + " " + req.body[0].lname , // REQUIRED.

    html: '<b>Customer Quote</b>' + '<br>' + 'Customer Name: ' + req.body[0].fname + " " +
    '<br>' + 'Message: ' + req.body[0].message + '<br>' + <b>Table</b>'+ '<br><br>' + content,
  };

  // The use of Transporter in reference to nodemailer is crucial for successful email delivery
  //     |                 
  //     |
  //     v
  // Transporter refers to the login details and sendit to the mail options


  transporter.sendMail(sendit, function (error, info) {// instead of (req, res, err) {
    if (error) { // instead of err just to avoid colision name
      console.log(error + "something strange...");
      res.status(401).send("that's all folk's");
    } else {
      res.status(200).send("nuthing here");
      console.log("Message sent! " );
    }

    transporter.close();
  });

return next();
});

Your code had an issue highlighted here :

transporter.sendMail(  sendit, function (  req, res, err)  {
//transporter.sendMail(sendit, function (error, info) {

    if (err) { 
      console.log(err + "something strange...");
      res.status(401).send("that's all folk's");

      // you are acting here on the 'info' coming from transporter.sendMail
     // not on 'res' from app.get('/send',      


    } else {
      res.status(200).send("nuthing here");
      console.log("Message sent! " );


   // you are acting here on the 'info' coming from transporter.sendMail
     // not on 'res' from app.get('/send',      

    }

Please incorporate the suggested changes above to address the problem you encountered. I hope this resolves your issue. :-)

Answer №2

Below you will find some suggested solutions and feedback:

app.get('/send', function (req, res, next) {
  // ...
  transporter.sendMail(sendit, function (req, res, next) { // This operation is asynchronous and will be completed later.
    // The argument `res` from the parent function is overshadowed by another `res` passed by `sendMail`.
    // It is uncertain whether `sendMail` passes the same `res` or a different one.
    // Consider renaming it to `res2`.
  }
  return next(); // Temporary call to the next middleware; all asynchronous tasks will be carried out at a later time.

Answer №3

transporter.sendMail(sendit,function(error, info){
if (error) {
    console.log(error + "something strange...");
    }

console.log("Message sent!");
});

    res.send("Messaage was Sent");

return next();
});

This solution was successful. Initially, attempting to include the res.send object within the transporter function caused it not to execute. Moving it outside resolved this issue, and I am now experiencing zero errors.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are some ways to monitor the movement of elements and activate functions at precise locations?

I am working on a project that involves a #ball element which, when clicked, utilizes jQuery animate to move downwards by 210px. The code I currently have is as follows: $('#ball').click(function() { $(this).animate({ top: '+=2 ...

Error Encountered on Heroku: Application Crashes While Attempting to Access Page Using Node.js and Express

index.js // Setting up an express app const express = require("express"); const app = express(); // Using express-static middleware for serving static files app.use(express.static("public")); // Defining the first route app.get(" ...

Occasionally, the function XMLHttpRequest() performs as expected while other times it may

I've encountered an issue with my XMLHttpRequest() function where it randomly works in both Chrome and IE. The function is triggered by On-click, but I'm having trouble catching the error. The only information I could gather is that readystate = ...

Guiding the user to a different React page after a successful login: a simple solution

Currently, I am working on developing my very first full-stack application with React for front-end and Node.js with Express for back-end. I have set up a /login route using react router dom where users can input their email and password ...

An element featuring a background color is vertically aligned in the middle of its parent container

Struggling to achieve a seemingly simple task, but coming up short on finding a solution. The goal is to have a background-color that aligns vertically in the middle of the first and last images in a stack of images. It may sound more complicated than it a ...

Alert: Firebase notification - User callback error. Something went wrong with the function and exceeded the maximum call stack size

I'm currently developing an e-commerce website featuring a shopping cart functionality using NodeJS (ExpressJS) and Firebase Database. Whenever I attempt to add an item to the cart, I encounter an error message stating that the Maximum call stack size ...

Parsing a CSV file using Node.JS and Express on the server side

Basically, I have set up a form for users to upload a CSV file. <form action="/upload" method="POST" enctype="multipart/form-data"> <div class="custom-file"> <input type="file" class="custom-file-input" id="customFile" name="fi ...

Unexpected behavior: Angular4/Javascript Date object alters when timezone is specified in Date constructor

In my Angular 4 application, I encountered an issue with a date retrieved from an API call. The date is in the format '1990-03-31T23:00:00-06:00' and when attempting to create a Date object and retrieve the month using getMonth(), it returns the ...

Attempting to use vue-test-utils-getting-started with the standard configuration results in a "Preset Not Found" error during

Currently, I am in the process of conducting a unit test by referring to the official guide provided. To do so, I have cloned the demonstration repository named vue-test-utils-getting-started. To replicate the issue, follow these steps: After cloning vu ...

Encountering a "Cannot GET /" error message

We are currently utilizing Next.js/React.js for our front-end, along with a server.js file that facilitates image uploads to the public/images/uploads directory. However, we are encountering an error message stating Cannot GET / when attempting to run the ...

Unable to dynamically populate Bootstrap select with real-time search and multiple options using jQuery

How can I dynamically populate a select statement with options retrieved from PHP code? <select name='friends[]' id='friends' class='selectpicker show-tick form-control' data-live- search='true' multiple& ...

Is there a way to prevent users from selecting certain days in ion-datetime?

After searching through the official documentation, I couldn't find a solution. I am in need of a function similar to the jQuery datepicker beforeshowday function. My goal is to disable all weekends (Saturday and Sunday) in upcoming dates so that user ...

Navigating the Angular Controller life cycle

I have set up my application states using ui-router: $stateProvider .state('app', { abstract: true, views: { 'nav@': { templateUrl: 'app/navbar.html', controller: 'NavbarController' ...

Is it possible for a mobile device to play .ogg videos?

Currently, I am setting up a server to stream videos using HTML. So far, I have tested playing both .mp4 and .ogg video formats on my computer successfully. However, when I attempted to play the same videos on a mobile device, only the .mp4 file showed u ...

Why does it seem like only one div is being added?

I am facing an issue with dynamically appending multiple div elements. Despite my efforts, only one div element is showing up on the browser when I try to test the code. I have searched for similar problems but could not find any solutions. Any assistanc ...

Incorporate a Variety of Elements onto Your Webpage

I have developed a custom tooltip plugin using JQuery, and I am implementing it on multiple A tags. Each A tag should have a unique tooltip associated with it, so I have the following code: var $tooltip = $("<div>").attr("id", tooltip.id).attr("cla ...

What is the proper placement for index.html <head/> class helper functions within a ReactJS Component?

My custom helper functions are stored in a JavaScript file called classie.js: ( function( window ) { 'use strict'; function classReg( className ) { return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); } var hasClass, ...

I'm a bit uncertain about the best placement for my progress bar component during the API call

Trying to grasp material ui I managed to implement the progress bar. Struggling with loading it until my data is fully loaded. Uncertain about where to place my progress bar component. Could you guide me on how to resolve this issue during API calls, so I ...

Images that adjust to different screen sizes within a grid layout

I have four images that need to be aligned in the following layout: ____________ |1 |4 | |_____| | |2 |3| | |__|__|______| They must be flush against each other, occupy 100% of the viewport's width, and most importantly, be respon ...

What is required to create a basic application that can function offline while featuring an HTML/CSS user interface?

Newbie inquiry: I am interested in creating a small application that can run offline on a desktop computer. The amount of data to be saved is minimal, so I have the option to use a file or some type of database. However, my main question is: What languag ...