{"id":653,"date":"2014-03-12T16:35:17","date_gmt":"2014-03-12T20:35:17","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/acts\/?p=653"},"modified":"2014-03-12T16:35:17","modified_gmt":"2014-03-12T20:35:17","slug":"using-jquery-in-node-with-jsdom","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/acts\/2014\/03\/12\/using-jquery-in-node-with-jsdom\/","title":{"rendered":"Using jQuery in Node with jsdom"},"content":{"rendered":"<p>After having watched a ton of Node.js tutorials (and TAing for a JS class), I decided a while ago &#8220;for my next script, I&#8217;m totally going to use Node.&#8221;<\/p>\n<p>So I finally got the opportunity this last week to write a script. Tasked with a menial job, making a script to accomplish it brightened my day. <\/p>\n<p>The first script was dealing with an xml api feed. So I immediately found xml2js, a nice converter and set about looping through some api urls, collecting the data I needed and totaling it up. It was a mess, and looked like this:<\/p>\n<p>var https = require(&#8220;https&#8221;);<br \/>\nvar parseString = require(&#8216;xml2js&#8217;).parseString;<\/p>\n<p>https.get(&#8220;https:\/\/someplace\/someapi&#8221;, function(response){<\/p>\n<p>\tvar body = &#8221;;<br \/>\n\tresponse.on(&#8220;data&#8221;, function(chunk) {<br \/>\n\t\tbody += chunk;<br \/>\n\t});<\/p>\n<p>\tresponse.on(&#8220;end&#8221;, function(){<br \/>\n\t\t\/\/console.log(body);<br \/>\n\t\tparseString(body, function (err, result) {<br \/>\n\t\t\ttotalEntries += result.feed.entry.length;<br \/>\n\t\t\tfor(var i=0; i < result.feed.entry.length; i++){\n\t\t\t\tsomething += parseInt(result.feed.entry[i]['something'][0]['somethingelse'][0].$.thingiwant);\n\t\t\t}\n\t\t\tconsole.log(\"Total stuff: \" + something);\t\t\t\t\t\t\t\t\t\n\t\t});\t\n\t});\n}\n[\/sourcecode]\n\nThis one was easy to get what I needed, but clearly not the right way to do it. Because the functions happen asynchronously, blah blah blah, that's not what I'm writing about.\n\nThe next one was very similar, but I had to scrape a webpage, not just xml data. So I found a nice lib called jsdom, which created a dom for me to use jquery on. \n\n[sourcecode language=\"javascript\"]\nvar jsdom = require(\"jsdom\");\n \njsdom.env(url, function(errors, window){\n\tvar $ = require(\"jquery\")(window);\n\tvar total = 0;\n\t\n\t$(\".some_class\").each(function(key, value){\n\t\t\/\/ just use a regex to get it\n\t\t\/\/ it's buried in the onclick, so I'll have to use a regex regardless...\n\t\tvar result = value.innerHTML.match(\/newWindow\\('([^']*)'\/)[1]; \/\/ get first grouping\n\t\tjsdom.env(host + result, function(errors, window){\n\t\t\tvar $ = require(\"jquery\")(window);\n\t\t\t\/\/ use regex to get the xxxxxxx because I'm lazy\n\t\t\tvar result = $('head').html().match(\/someRegex\/g);\n\t\t\tif(result !== null){\n\t\t\t\tfor(var i = 0; i < result.length; i++){\n\t\t\t\t\tvar thing = result[i].match(\/\"([^\"]*)\"\/)[1]; \/\/ get first grouping\n\t\t\t\t\ttotal += thing;\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t});\n\t});\n});\n[\/sourcecode]\n\nThis was super easy \/ super powerful to use something I'm already so familiar with to accomplish a task that is well suited to that. The scripts themselves took minutes to write -- if you don't take into account the time I spent finding where to get what I needed.\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After having watched a ton of Node.js tutorials (and TAing for a JS class), I decided a while ago &#8220;for my next script, I&#8217;m totally going to use Node.&#8221; So I finally got the opportunity this last week to write a script. Tasked with a menial job, making a script to accomplish it brightened my [&hellip;]<\/p>\n","protected":false},"author":4571,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17295,1],"tags":[63973,111249,111250],"class_list":["post-653","post","type-post","status-publish","format-standard","hentry","category-javascript","category-uncategorized","tag-jquery-2","tag-node-js","tag-scripting"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/users\/4571"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/comments?post=653"}],"version-history":[{"count":1,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/653\/revisions"}],"predecessor-version":[{"id":656,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/653\/revisions\/656"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/media?parent=653"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/categories?post=653"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/tags?post=653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}