Tayyab
Tayyab

Reputation: 47

Error: Cannot find module 'node-jsdom

I have two files todosController.js and index.html. I am trying to access an element and see the output of it in javascript console. here is the code:

<!--index.html:--> 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TodosList</title>
</head>
<body>
   <h1>Todos List</h1>
   <button id="displayTodosButton">Display Todos</button>
   <!--index.html is linked to javascript file todosController.js-->
   <script src="todosController.js"></script>
</body>
</html>

Here is JavaScript code:

  //todosController.js

var jsdom = require("node-jsdom");
var fs = require("fs");
var jquery = fs.readFileSync("./jquery.js", "utf-8");

jsdom.env({
url: "http://news.ycombinator.com/",
src: [jquery],
done: function (errors, window) {
    var $ = window.$;
    console.log("HN Links");
    $("td.title:not(:last) a").each(function () {
        console.log(" -", $(this).text());
    });
}
});
let markup = fs.readFileSync('foo.html');
let doc = jsdom(markup, {});

function showData() {
    elem = doc.getElementById('TodosText').value;
}

showData();

I am using Webstorm as an IDE.I tried to install npm jsdom as recommeded in some of the answers below but the issue is still the same.

Here is the error:

module.js:538
    throw err;
    ^

Error: Cannot find module 'node-jsdom'
   at Function.Module._resolveFilename (module.js:536:15)
   at Function.Module._load (module.js:466:25)
   at Module.require (module.js:579:17)
   at require (internal/module.js:11:18)
   at Object.<anonymous> 
   (/Users/muhammadtayyabsaeed/WebstormProjects/Todo 
   List/js/todosController.js:89:13)
   at Module._compile (module.js:635:30)
   at Object.Module._extensions..js (module.js:646:10)
   at  Module.load (module.js:554:32)
   at tryModuleLoad (module.js:497:12)
   at Function.Module._load (module.js:489:3)

I would appreciate your response.

Upvotes: 0

Views: 6530

Answers (3)

lena
lena

Reputation: 93728

Please try creating the following project in WebStorm:

package.json:

{
  "name": "node_dom",
  "version": "0.0.1",
  "dependencies": {
    "jsdom": "^11.3.0"
  }
}

todosController.js

const jsdom = require("jsdom/lib/old-api.js");
const jsdom_hard = require("jsdom/lib/old-api.js").jsdom;
const fs = require('fs');

jsdom.env(
  "http://news.ycombinator.com/",
  ["http://code.jquery.com/jquery.js"],
  function(err, window) {
    const $ = window.$;
    console.log("HN Links");
    $("td.title:not(:last) a").each(function() {
      console.log(" -", $(this).text());
    });
  }
);

let markup = fs.readFileSync('foo.html');
let doc = jsdom_hard(markup, {});


function showData() {
  elem = doc.getElementById('TodosText').innerHTML;
  console.log("Element value: " + elem)
}

showData();

foo.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>TodosList</title>
</head>
<body>
<div id="TodosText">Hello!!</div>
</body>
</html>
  • right-click the package.json, choose Run "npm install"
  • once dependencies are installed, right-click the todosController.js, choose Run

this should do the thing

Upvotes: 1

Jose
Jose

Reputation: 31

I twisted your code a little bit, so here it goes

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>TodosList</title>
</head>

<body>
  <h1>Todos List</h1>
  <input type="text" id="TodosText">
  <input type="button" id="displayTodosButton" value="Display Todos" onClick="showData();">

  <script>
    function showData() {
      elem = document.getElementById('TodosText').value;
      console.log(elem);
    }
  </script>

</body>

</html>

In this sample I put the script in the html file but feel free to use as you wish. Also added a text field and changed the button to a simple html one and the call to showData on it.

Hope it helps!

Upvotes: 0

doubleOrt
doubleOrt

Reputation: 2507

Add this code at the beginning of your JS and run the JS file instead of running HTML (replace foo.html with the path from your JS file to your HTML file):

var fs = require('fs');
var jsdom = require("jsdom").jsdom; 
var markup = fs.readFileSync('foo.html');
var doc = jsdom(markup, {});

Then try accessing the document as doc instead and see if that works.

The thing is, document is only defined in browser environments, not in the WebStorm console, which is why your code is working in Chrome (I am not an expert on WebStorm, but I believe it runs JS code in a nodeJS environment where a document is not defined).

Take a look at this thread (which is also where I snatched the above example from).

Upvotes: 0

Related Questions