Having trouble loading CSS file in node js after submitting form

Before diving into more details, let me explain my current situation. I am utilizing node's nodemailer to facilitate the process of sending emails based on the information submitted through a form. Initially, everything was functioning smoothly when there was only one recipient and one HTML body, which were sent together. However, I encountered an issue when I introduced mailOptions2 within a for loop to enable sending emails with recipients and HTML bodies stored in separate arrays. Despite the emails and HTML content being sent, they were not aligned as intended. Additionally, upon form submission, the /send state kept loading indefinitely, eventually displaying the raw HTML of the page without any CSS applied. The error message I received was as follows:

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:489:11)
    at ServerResponse.setHeader (_http_outgoing.js:496:3)
    at ServerResponse.header (C:\Users\Ahmet Ömer\Desktop\Repairtechnician\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\Users\Ahmet Ömer\Desktop\Repairtechnician\node_modules\express\lib\response.js:170:12)
    at done (C:\Users\Ahmet Ömer\Desktop\Repairtechnician\node_modules\express\lib\response.js:1004:10)
    at Immediate._onImmediate (C:\Users\Ahmet Ömer\Desktop\Repairtechnician\node_modules\express-handlebars\lib\utils.js:26:13)
    at runCallback (timers.js:781:20)
    at tryOnImmediate (timers.js:743:5)
    at processImmediate [as _immediateCallback] (timers.js:714:5)

Despite encountering similar posts about this error, I struggled to find a resolution that matched my specific scenario, mainly due to my limited experience as a beginner.

Node.js Configuration:

app2.engine('handlebars', exphbs2());
app2.set('view engine', 'handlebars');

// Static folder
app2.use('/public', express2.static(path2.join(__dirname, 'public')));
app2.use('/', express2.static(path2.join(__dirname, '')));

// Body Parser Middleware
app2.use(bodyParser2.urlencoded({ extended: false }));
app2.use(bodyParser2.json());

app2.get('/', (req, res) => {
  res.render('services');
});

app2.post('/send', (req, res) => {
  let mailList = ['xyz', '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b3cbcac9f3d4ded2dadf9dd0dcde">[email protected]</a>'];
  let outputs = [
    `
    <div>
    </div>  
  `,
  `
   <div>
   </div>  
`];

  // create reusable transporter object using the default SMTP transport
  let transporter2 = nodemailer2.createTransport({
    service: 'gmail',
    port: 25,
    secure: false,
    auth: {
        user: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7d0504073d1a101c1411531e1210">[email protected]</a>', // senders email
        pass: 'xyz' // senders password
    },
    tls:{
      rejectUnauthorized:false
    }
  });

  for ( var i = 0; i < mailList.length; i++) {
      // setup email data with raw html
      let mailOptions2 = {
        from: '"xyz" <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9ee6e7e4def7f0f8f1b0fdf1f3">[email protected]</a>>', // sender address
        to: mailList[i], // receiver or receivers
        subject: 'xyz', // Subject line
        html: outputs[i] // html body
    };

        // send mail with defined transport object
      transporter2.sendMail(mailOptions2, (error, info) => {
        if (error) {
            return console.log(error);
        }
        console.log('Message sent: %s', info.messageId);   
        console.log('Preview URL: %s', nodemailer2.getTestMessageUrl(info));

        res.render('services', {msg2:'xyz'});
    });
  }
});

Essentially, using a for loop for mailOptions2 to assign distinct values to specific areas caused the aforementioned issues. If I had avoided this approach, the functionality would have operated without any complications.

Below is the structure of the relevant files for your reference:

server.js
services.html
public
   css
      styles.css

Answer №1

It's important to note that calling res.render() multiple times is not recommended because it sends the compiled HTML to the client each time. Instead, you should only call res.render() when you are ready to send the final response to your client.

In situations like this, utilizing Promises can help manage the sendMail callback effectively:

// declare sendMailPromises array outside the for loop
let sendMailPromises = [];

// code inside the for loop
let promise = new Promise((resolve, reject) => {
    transporter2.sendMail(mailOptions2, (err, infos) => {
        if(err) reject(err)

        console.log('Mail sent %s', info.messageId);
        console.info('Preview URL: %s', nodeMailer2.getTest(info));
        resolve(infos)
    });

});
sendMailPromises.push(promise);

// code after the for loop
Promise.all(sendMailPromises)
    .then(() => {
        res.render(mailOptions, {msg2: '...'})
    }).catch((err) => {
        console.error(err);
    })

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 steps are involved in setting up a SAML service provider using @node-saml/node-saml?

I'm currently working on a SAML SP implementation using the @node-saml/node-saml library. Despite creating the necessary source code, I am facing an issue with the SAML authentication not functioning as expected. Can anyone provide guidance on how to ...

Eliminate the space between the navigation bar and carousel when using Materialize with Vue.js and Laravel

I am facing an issue with the gap between the navbar and carousel in my materialize design. I have implemented Vue components for each div and Laravel as the backend. Using Sass for CSS preprocessing, I attempted to adjust the margins for the body, navbar, ...

The program is unable to identify the function .modal("show") upon adding HTML to the page

I'm currently developing a program that utilizes a click event handler to trigger an ajax request to my node server. The server then generates information within a handlebars partial and sends it back to the client using res.render("partials/scraped-a ...

Tips for inserting HTML-tagged data into a database using AJAX and PHP

var id=$("#id").val(); var status=$("#status").val(); var jtitle=$("#jtitle").val(); function submitData(){ var id=$("#id").val(); var status=$("#status").val(); var jtitle=$("#jtitle").val(); var jdesc=tinyMCE.acti ...

An error has occurred in nodejs: headers cannot be set after they have already been sent

I'm a newcomer to Node.js and encountering some challenges. Whenever I attempt to open 127.0.0.1:3000/bejelentkezes, I encounter the following error: POST /bejelentkezes 500 550.784 ms - 2259 GET /css/404.css 304 2.751 ms - - 1 Successful login Erro ...

Modify the BehaviorSubject upon clicking or focusing on the input

I have created a directive for an input field. I want to trigger a flag in another component when the input is clicked or focused upon. @Directive({ selector: '[appDatepicker]' }) export class DatepickerDirective implements DoCheck{ constru ...

Javascript code requires server to have default text field values

Based on the choice made by a user, a text field box will either remain concealed or revealed: $("#aForm").on("change", function() { if ($(this).val() == "a") $("#textField").hide(); else $("#textField").show(); }); The issue arises when the ...

Strategies to manage or prevent a timezone offset while deploying a Next.js application on Vercel

Is there a way to ensure that a React/Next.js App always displays the local time in CEST, regardless of the user's location? For example, if I receive GMT time from the backend and want to offset it to display the CEST timezone, how can I achieve this ...

What is the process for converting NDC coordinates to camera space within a vertex shader?

I am currently maintaining a vertex shader contained within a custom material class (originally inherited from ShaderMaterial but now from MeshStandardMaterial) which converts 3D coordinates to Normalized Device Coordinates (NDC) as usual: vec4 ndcPos = pr ...

What steps should I take to fix the error message "Uncaught TypeError: Class constructor m must be called with 'new'" that occurs while attempting to access a polymer v2.0 application?

Is there a way to resolve this error that occurs when attempting to open a Polymer v2.0 app on Safari in iOS? Uncaught TypeError: Class constructor m cannot be invoked without 'new' from custom-elements-es5-adaptor. The Polymer v2.0 starter k ...

What specific pieces of information are contained within Pinterest image URLs?

Before the underscore, the first part is the ID of the pin...what exactly are the ZZtfjmGQ used for? I'm guessing the _c probably indicates something about the size. http://media-cache-lt0.pinterest.com/upload/33284484717557666_HZtfjmFQ_c.jpg I am c ...

Is the text in bold format or not detectable in contenteditable mode?

I am currently working on developing a custom text editor using the built-in contenteditable feature in HTML. I am trying to figure out how to determine whether the selected text is bold or not within the editor. This is what my current setup looks like: ...

The jQuery functions seem to be malfunctioning when trying to retrieve elements by their ids

I'm having trouble with the click function when using IDs, but it works fine with classes. $('#myTab li a').click(function(e) {} When I switch to using classes like this: $('.nav-tabs a.overview').click(function(e) {} it work ...

What is more costly in terms of performance: toggling the visibility of a DOM node or adding/removing a DOM node?

When it comes to calling, which is the more costly operation? Displaying and hiding a DOM node Creating and deleting DOM nodes Let's assume we only have one or a few (less than 5) nodes that require manipulation, and the application is running on a ...

Leveraging Flexbox and flexGrow in conjunction with Textfield

I am looking to use Flexbox to separate my components on the screen in a way that positions them correctly. I have 3 rows with textfields that need specific ratios related to the full width: row 1 : 2, 1, 1 row 2 : 1, 1 row 3 : 1, 1, 2 I attempted to ach ...

Expanding a dropdown list on the fly using vanilla JavaScript

I am restricted to using Vanilla JavaScript only, without any additional libraries like jQuery. Initially, I attempted to store all registered items in a global array and then use a forEach loop to append an <option> child to the <select>. How ...

Tips for assigning an ID to a span element within a for loop

I am facing a challenge where I need to assign IDs to span tags that do not have the id attribute. These IDs need to be assigned sequentially by incrementing through a for loop and passing my geneologicalSequenceNumber into each span tag. Can you guide me ...

Guide to creating a Discord bot that replies privately to users without other channel members being able to see the messages

As a newcomer to Discord, I am attempting to create a bot that will respond to user commands by sending a reply that only the user who issued the command can see. However, I am struggling to figure out how to implement this feature. Below is the source c ...

Explore the world of textures transferring from Maya to Three.js

I'm looking to convert a Maya model to JavaScript for a simple model with textures. The conversion works fine, but the textures are not showing up. Here is my code: var loader = new THREE.JSONLoader(); loader.load( "models/t2.js", function(geometry) ...

What is the best way to incorporate an apostrophe into a string so that it can be displayed in a tooltip using jQuery

There is a text or string stored inside the 'data' variable, containing some texts with apostrophes. The issue I'm facing is that the tool tip is not displaying the text after the apostrophe symbol. How can I include all texts, including apo ...