Stacey
Stacey

Reputation: 73

How to call a node js function from a separate front end javascript function

I have a node js backend (app.js), which is connected to a html, css, and javascript (script.js) front end.

In my HTML I have a form that gets an image, which then calls a function in script.js.

Script.js then uploads the file using ajax and jquery, which works fine.

Once that's complete, I want it to automatically call a function I have in app.js that calls a python script.

This function works on its own, but I'm having problems connecting both the file upload and the python script. Right now I get an error when I upload the image that says that app is not defined. How can I call both of these in one function?

Relevant HTML:

<form id="form">
     Select your image: <input type="file"  name="myfile" id="myfile" accept="image/x-png,image/jpeg"><br/>
     <input type="submit" value="Submit" class="getCodeButton"/>
 </form>
<div id="status"></div>

Relevant node js (app.js):

const express = require('express')
    const bodyParser = require('body-parser')
    const multer  = require('multer')
    const sharp = require('sharp')
    
    const app = express()
    app.use(bodyParser.urlencoded({ extended: false })); 
    app.use(bodyParser.json());
    
    app.use(express.static('./public')) 
    app.use(express.static('./uploads/'))
    
    app.get('/', (req, res)=>{
        res.sendFile("index.html", { root: __dirname + "/public" })
    })
    
    const port = process.env.PORT || 8000
    app.listen(port, 
        ()=>console.log(`Server running on port ${port}`))
        
    const upload = multer().single('myfile')
    app.post('/upload', (req, res)=>{
        upload(req, res, async function(err){ 
         if( err|| req.file === undefined){
             console.log(err)
             res.send("error occured")
         }else{
            let fileName = "myfile.jpeg"
            var image = await sharp(req.file.buffer)
            .jpeg({
                quality: 40,
            }).toFile('./uploads/'+fileName)
            .catch( err => { console.log('error: ', err) })
            res.send(req.body)
         }
        })
    })
app.get('/runPython1', (req, res) => {
 
    var dataToSend;
    const python = spawn('python', ['qr_vision.py', 'uploads/myfile.jpeg']);
    python.stdout.on('data', function (data) {
    console.log('Pipe data from python script ...');
    dataToSend = data.toString();
    });
    python.on('close', (code) => {
    console.log(`child process close all stdio with code ${code}`);
    //console.log(dataToSend)
    res.send(dataToSend)
    });
 
})

Relevant javascript (script.js):

document.getElementById('form').onsubmit = function(event){
    event.preventDefault()
    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("status").innerHTML = 'sent'+this.responseText+ xhttp.status;
      }else{
        document.getElementById("status").innerHTML = xhttp.status ;
      }
    }

    xhttp.open("POST", "upload")
    var formData = new FormData()
    formData.append('myfile', document.getElementById('myfile').files[0])
    xhttp.send(formData)
    
    app.get('/runPython1', (req, res) => {
        console.log(res.result)
    });
}

Upvotes: 0

Views: 1511

Answers (1)

GokulnathP
GokulnathP

Reputation: 712

You can do it in several ways

  1. From frontend: Write an another XMLHttpRequest to call runPython1 endpoint and send the request once the upload one is completed.
  2. From nodejs backend: Instead of exposing runPython1 as api endpoint, you can have it as function and call it once the upload is completed.
app.post('/upload', (req, res)=>{
        upload(req, res, async function(err){ 
         if( err|| req.file === undefined){
             console.log(err)
             res.send("error occured")
         }else{
            let fileName = "myfile.jpeg"
            var image = await sharp(req.file.buffer)
            .jpeg({
                quality: 40,
            }).toFile('./uploads/'+fileName)
            .catch( err => { console.log('error: ', err) })
            runPython1(res);
         }
        })
    })

const runPython1 = (res) => {
 
    var dataToSend;
    const python = spawn('python', ['qr_vision.py', 'uploads/myfile.jpeg']);
    python.stdout.on('data', function (data) {
    console.log('Pipe data from python script ...');
    dataToSend = data.toString();
    });
    python.on('close', (code) => {
    console.log(`child process close all stdio with code ${code}`);
    //console.log(dataToSend)
    res.send(dataToSend)
    });
 
}
  1. You can also redirect to runPython1 endpoint once the upload finished. Refer This site for redirecting

Upvotes: 1

Related Questions