Import querySelector function

#1

Hello,
I was wondering if could I import such function like querySelector or querySelectorAll to use it inside function node?

I've tried with:
var doc = msg.payload;
var querySelector = global.get('querySelector');
doc.querySelector("p");

without success...

0 Likes

#2

querySelector is not a defined function in node.js - its a browser specific feature.

There are npm modules available to provide similar functionality, such as cheerio you could add via functionGlobalContext, but for the example code you show, you can use the core HTML node to do pretty much exactly that.

0 Likes

#3

Thank you, but I would like to import a whole html page inside msg.payload then assigne some string to variables using css selectors in one function node using for example querySelector function.

So should I install npm cheerio gloabally then import it?
var querySelector = global.get('cheerio');

0 Likes

#4

You should following the docs for loading additional modules here: https://nodered.org/docs/writing-functions#loading-additional-modules

0 Likes

#5

ok, thank you.
I installed https://www.npmjs.com/package/query-selector then add line to settings.js:
functionGlobalContext: {
qs:require('query-selector')
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},

then restart node-red and import it by:
var doc = msg.payload;
var qs = global.get('qs');
doc.qs("p");

I got the same issue:
TypeError: doc.qs is not a function

0 Likes

#6

From the readme of the query-selector module you have chosen shows it has to be used alongside jsdom:

var querySelectorAll = require('query-selector');
var jsdom = require("jsdom").jsdom;
var doc = jsdom('<html><div id="t"><span>1</span><span>2</span></div></html>');
var time = Date.now();
console.log(doc.querySelectorAll('#t span', doc).length);
0 Likes

#7

ok i see...
ok jsdom installed and added:
functionGlobalContext: {
qs:require('query-selector')
jsdom:require('jsdom')
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},

and... TypeError: doc.qs is not a function

0 Likes

#8

Did you modify your Function to match? (and when sharing code please follow the guidance in this post: How to share code or flow json)

0 Likes

#9

sure:

var doc = msg.payload;
var qs = global.get('qs');
var jsdom = global.get('jsdom');
doc.qs("p");

[{"id":"8d1a968.84be568","type":"inject","z":"fb6d8306.816e6","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":300,"y":240,"wires":[["c1b49fbb.618cc"]]},{"id":"c1b49fbb.618cc","type":"http request","z":"fb6d8306.816e6","name":"","method":"GET","ret":"txt","url":"http://m.traxelektronik.pl/index.php?type=2&elid=2666","tls":"","x":470,"y":260,"wires":[["48a65208.9610ac"]]},{"id":"48a65208.9610ac","type":"function","z":"fb6d8306.816e6","name":"","func":"var doc = msg.payload;\nvar qs = global.get('qs');\nvar jsdom = global.get('jsdom');\ndoc.qs(\"p\");","outputs":1,"noerr":0,"x":700,"y":300,"wires":[["8cf50587.b5dd98"]]},{"id":"8cf50587.b5dd98","type":"debug","z":"fb6d8306.816e6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":670,"y":140,"wires":[]}]```
0 Likes

#10

So you import jsdom into your function, but you haven't used it.

Look again at the query-selector example code. Look at where its doc variable comes from.

(and please use the ``` quotes around blocks of function code in the same way you did your flow).

0 Likes

#11

Ok, I installed cherio as you recommend.
Another problem:
[{"id":"8d1a968.84be568","type":"inject","z":"fb6d8306.816e6","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":300,"y":240,"wires":[["c1b49fbb.618cc"]]},{"id":"c1b49fbb.618cc","type":"http request","z":"fb6d8306.816e6","name":"","method":"GET","ret":"txt","url":"http://m.traxelektronik.pl/index.php?type=2&elid=2666","tls":"","x":470,"y":260,"wires":[["48a65208.9610ac"]]},{"id":"48a65208.9610ac","type":"function","z":"fb6d8306.816e6","name":"","func":"var doc = msg.payload;\n//var qs = global.get('qs');\n//var jsdom = global.get('jsdom');\n//doc.qs(\"p\");\nglobal.get('cherio');\ndoc.nextAll('p')","outputs":1,"noerr":0,"x":690,"y":300,"wires":[["8cf50587.b5dd98"]]},{"id":"8cf50587.b5dd98","type":"debug","z":"fb6d8306.816e6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":670,"y":140,"wires":[]}]

TypeError: doc.nextAll is not a function

I would like to get this value:


from
http://m.traxelektronik.pl/index.php?type=2&elid=2666

I know that this is possible by html node with selector... I would like to get the same using function node.

0 Likes

#12
var doc = msg.payload;
//var qs = global.get('qs');
//var jsdom = global.get('jsdom');
//doc.qs("p");
global.get('cherio');
doc.nextAll('p')

I don't see any code using cheerio. In the same way you never used jsdom.

Simply loading the module does not mean doc suddenly has all of these extra methods you are trying to use.

Here is the example for Cheerio from its own README:

const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')
 
$('h2.title').text('Hello there!')

Note how it actually uses the cheerio library.

0 Likes