1

I'm trying to do a simple thing. I have a website and I want people to be able to send some feedback and warn me, for that i have a "Notify Owner" button which displays a form and on Submit should execute a python script that send myself an email with the information they filled.

This is my form code (index.html - Created on the client side)

<script>
async function notifyOwner() {
  await fetch("api/notify", { method: "post" }).catch(console.log);
}
</script>

<div class="form-popup" id="myForm">
      <form class="form-container" name="form-owner">
        <h1>Notify Owner</h1>
        <label><b>Name</b></label>
        <input id="name" style="width:90%" type="text" placeholder="Enter your name$        
        <label><b>Message</b></label>
        <input id="context" style="width:90%" type="text" placeholder="Enter Reason$
        <button type="submit" class="btn" onclick="notifyOwner()">Submit</button>
        <button type="button" class="btn cancel" onclick="closeForm()">Close</butto$
      </form>
</div>

This is my server side handling

app.post("/api/notify", async (req, res) => {
  try{
    var subject = "teste";
    var body = "ok";
    child_process.execSync('python3 sendEmail.py ' + subject + " " + body);
  }catch(error){
    console.error(error);
  }
});

what should I do to replace the var subject with the value from id="name" and replace the var body with the value from id="context"?

isherwood
  • 58,414
  • 16
  • 114
  • 157
André Clérigo
  • 846
  • 1
  • 10
  • 30
  • 1
    May I suggest sending the email using the nodejs client ? It seams far fetch to call a python script from a nodeJS app, just to send an email. There is plenty of nodejs email library available. – Nicolas Dec 07 '20 at 15:01
  • Are you asking how to get input values in JavaScript? Does this answer your question? https://stackoverflow.com/questions/11563638/how-do-i-get-the-value-of-text-input-field-using-javascript – isherwood Dec 07 '20 at 15:01
  • I'll defintly give it a try! Even though I've searched for it, maybe I don't know enough from nodejs to properly search it :D – André Clérigo Dec 07 '20 at 15:03
  • @isherwood I think that document.getElementById doesnt work because the server didn't deploy the form, the form is done on client side and i call the script on the server side. I was more interested on knowing how to transfer the data from the html to the server – André Clérigo Dec 07 '20 at 15:05
  • NodeJS is just JavaScript. Widen the scope of your research. – isherwood Dec 07 '20 at 15:05
  • @Nicolas I still have the same problem with a library, how can i transfer the data from the client form to a variable in the nodejs server – André Clérigo Dec 07 '20 at 15:13

2 Answers2

1

SOLVED

On the server side.

app.use(express.json());
app.post("/api/notify", async (req, res) => {
    try{
        const subject = req.body.sub;
        const body = req.body.cont;
        child_process.execSync('python3 sendEmail.py ' + subject + " " + body);
    }catch(error){
        console.error(error);
    }
});

On the client side.

<script>
async function notifyOwner(ele) {
  const name = document.getElementById("name");
  const context = document.getElementById("context");
  await fetch("api/notify", {
    method: "POST",
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({sub: name.value, cont: context.value})
  }).catch(console.log);
}
</script>
<button type="submit" class="btn" onclick="notifyOwner(this)">Submit</button>
André Clérigo
  • 846
  • 1
  • 10
  • 30
0

In client script tag:

async function notifyOwner(ele) {
  const form = ele.parentElement.parentElement
  await fetch("api/notify", { 
    method: "POST",
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({data form.whatever}) // Replace whatever with whatever data you want to send from the form
  }).catch(console.log);
}

HTML:

...
        <button type="submit" class="btn" onclick="notifyOwner(this)">Submit</button>
...

Pass this to notifyOwner

In Server:

app.use(express.json());

app.post("/api/notify", async (req, res) => {
  try{
    const { data } = req.body; // Get key that was sent
  }catch(error){
    console.error(error);
  }
});
Faraz
  • 433
  • 3
  • 7
  • Do i need to install any library to use bodyParser? – André Clérigo Dec 07 '20 at 15:41
  • It was `express.json()` not `express.bodyparser()` sorry. And Nope, if you're using Express 4.16+. – Faraz Dec 07 '20 at 15:49
  • var subject is null – André Clérigo Dec 07 '20 at 15:54
  • Try loggin `ele.parentElement.parentElement.getAttribute('id')` in `notifyOwner` and see if it actually returns the id – Faraz Dec 07 '20 at 15:59
  • sorry I had a typo. My var subject is returning 'myForm' which is the id of the div that contains the form, which is not what i need. – André Clérigo Dec 07 '20 at 16:05
  • you can then remove the `.id` part and use the raw html element to query all the fields in the form that you need. The concept remains the same, you send the data in the body of the post request and access it on the server the same way. You can also simply destructure the request body on the server: `const {id, ...} = req.body;` – Faraz Dec 07 '20 at 16:27
  • if i replace getAttribute('id') to .innerHTML i just get the Form html code, what should i change it to get the values of the inputs? – André Clérigo Dec 07 '20 at 16:35
  • No, you ned to use ether `querySelector()`, `getElementById()` or something similar to query elements in the form. Your form element is - `ele.parentElement.parentElement`, now you will have to actually get the stuff from within your form. If you want to get for example the input field with `id="context"` then you would do - `const input = ele.parentElement.parentElement. getElementById('context');` then if you want to get the text the user entered you would do `const text = input.value;` – Faraz Dec 07 '20 at 16:38
  • and then do body: JSON.stringify({id: text}) ? – André Clérigo Dec 07 '20 at 16:46
  • yes that will send the content of the input field to the server, then in server you can do ` var subject = req.body.id;`. Also use a key that makes sense in-place of `id`. – Faraz Dec 07 '20 at 16:48
  • okok, if i do that my var subject has no value and on the browser log i have this error: Uncaught SyntaxError: Unexpected identifier] on the line that i have ```const input = ele.parentElement.parentElement.getElementById('name');``` – André Clérigo Dec 07 '20 at 16:51
  • try `const input = ele.parentElement.parentElement.querySelector('#name').value` – Faraz Dec 07 '20 at 16:59
  • the const input code should be before the body on the async func right? – André Clérigo Dec 07 '20 at 17:01
  • it should be before your fetch request. – Faraz Dec 07 '20 at 17:06
  • ```async function notifyOwner(ele) { const input = ele.parentElement.parentElement.getElementById('name'); const text = input.value; await fetch("api/notify", { method: "POST", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({sub: text}) }).catch(console.log); }``` and req.body.sub on the server and doesn't work – André Clérigo Dec 07 '20 at 18:08
  • please try `querySelector(#name)` instead of `getElementById('name')`. – Faraz Dec 07 '20 at 18:09
  • (index):16 Uncaught SyntaxError: Unexpected identifier on the console in the web – André Clérigo Dec 07 '20 at 18:44