skip to Main Content

I’m trying to add a JavaScript function that I wrote myself, to an HTML button which I also did myself. I’m having problems calling the document.getElementById() function because I’m working with Node.js. I read in some other forum, you can work around that with JSDOM. Now I’m having problems with that. Is there any other solution which is easier than the JSDOM-way? I also can’t really use JSDOM because it would require a new installation which couldn’t be done in the intire team time-wise.

JS code

const fetch = require("./fetch");
const jsdom = require('jsdom');
const http = require('http');
const fs = require('fs');
var url = require('url');
const  port = 3000



const server = http.createServer(function(req, res) {
    
    var q = url.parse(req.url);
    var filename = "." + q.pathname;
    console.log(req.url)

    if (req.url == '/') {
        res.writeHead(301, { Location: 'http://localhost:3000/frontpage.html' })
        res.end()
        } else {
            res.writeHead(200, { 'Content-Type': 'text/html' })
            fs.readFile(filename, function(error, data) {
                if(error) {
                    res.writeHead(404)
                    res.write('Error: File Not Found')
                } else {
                    res.writeHead(200, { 'Content-Type': 'text/html' })
                    res.write(data)
                }
                return res.end()
            })
    }
})

server.listen(port, function(error) {
    if (error) {
        console.log('Something went wrong', error)
    } else {
        console.log('Server is listening on port ' + port)
    }
})






const { JSDOM } = jsdom;

const { document } = (new JSDOM('frontpage.html')).window;
global.document = document;
var button = document.getElementById("meinButton")
button.addEventListener("click", fetch.register_medication);

HTML Elements

    <script scr="fetch.js"></script>
    
    <button id="meinButton">Klick mich!</button>

2

Answers


  1. I’m not sure what you’re trying to do with JSDOM here, but from reading your question, I think you just want the button on your page to do a post to your api more info here

    Then where your node app is responding to requests, you can detect the REST API call and do your work there like this:

    if (req.url == '/') {
      // ...the stuff here is fine as is
    }else if (req.url.indexOf("register_medication") == 0){
      // call your behaviour here
    }
    

    If you wanted to serve the page with modifications in for the user, you’d need to take care of that before serving the file, but I don’t think that’s what you want?

    Login or Signup to reply.
  2. It looks like you’ve gotten your serverside code and your clientside code mixed up. NodeJS is for the server; clientside activity such as adding an event handler to a button should be running in the client, not embedded inside a node script. It can be confusing, since both are written in the same language (with different libraries available), and some modern toolchains and libraries kind of conceptually blur the difference between serverside and clientside code — but they’re executed in completely different contexts and can’t be intermingled.

    This first part of your code is meant for the node server, and will be executed on the host; it looks like what it’s doing is checking the (server’s) filesystem for paths that match the url, reading them using fs, and sending the contents on to the browser:

    const server = http.createServer(function(req, res) {
        var q = url.parse(req.url);
        var filename = "." + q.pathname;
        if (req.url == '/') {
            res.writeHead(301, { Location: 'http://localhost:3000/frontpage.html' })
            res.end()
            } else {
                res.writeHead(200, { 'Content-Type': 'text/html' })
                fs.readFile(filename, function(error, data) {
                    if(error) {
                        res.writeHead(404)
                        res.write('Error: File Not Found')
                    } else {
                        res.writeHead(200, { 'Content-Type': 'text/html' })
                        res.write(data)
                    }
                    return res.end()
                })
        }
    })
    
    server.listen(port, function(error) {
        if (error) {
            console.log('Something went wrong', error)
        } else {
            console.log('Server is listening on port ' + port)
        }
    })
    

    (I’m far from expert in Node, so I’m not sure if that’s the best way to do what it’s doing, but it looks like it should work.)

    This next part, though, is plain javascript. It should be run in the browser, not on the server:

    var button = document.getElementById("meinButton")
    button.addEventListener("click", fetch.register_medication);
    

    The simplest way to accomplish that would be to store this in its own .js file, separate from the node scripts, and have each web page that needs it load it using <script src="/path/to/clientside.js">. (This path should be relative to the web root, just like for images or css files; it will not be the same as your nodejs paths). Node itself doesn’t need to know anything about this .js file; it’ll be requested directly by the browser and executed there.

    jsdom is part of Node which is used to perform DOM operations before sending the html to the browser, which is useful in some situations but for much more complicated use cases than what you’re dealing with here. You can skip all that and go straight to the getElementById fun.

    (In a comment you mentioned trying to separate the js but getting the error "ReferenceError: document is not defined" — that’s a Node error message, which suggests that you were still trying to run the script on the server instead of in the browser. Make sure it’s the web page itself, not node, that requests any js that should run in the browser.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search