I had tried Jquery, Parse5, JsDom, and found that they can't work in nativescript. Jquery is Dom-dependent, and Parse5 and JsDom depend on Node.js which is not supported by nativescript now. What I want is only a html-parser, is it possible to import jquery into nativescript using as a hmtl-parser? If it's possible how can I make it.If not, Is there a handy html-parser can be used in Nativescript(With Angular2 + TypeScripyt)。
Details about my application.
I am developping a mobile app for moodle use nativescript。My app communicates with moodle by moodle's rest api, and some content of it is html string. So I need a html-parser to get the things in that html-string.
For example, I send a "mod_quiz_get_attempt_data" request to moodle. And I will fetch a json response as below:
{"questions": [
{
"slot": 1,
"type": "multichoice",
"page": 0,
"html": "Html string here.Can be very complex.I can't post html-string, stackoverflow ignore them",
}
]
}
Some data I need is in the "html" part which is html-string.Because moodle is a third party,So I prefer to handle this in my app。
#Marek Maszay, #Emil Oberg
#Emil Oberg, I have given cheerio a try.It doesn't work.Because cheerio depends on htmlparser2 which is also depend on Nodejs.
As you've been looking at jQuery (among others) I'd say that Cheerio is what you want. It is an implementation of core jQuery designed for a non-DOM environment (such as in a NativeScript app, on the server, etc).
However, parsing HTML is commonly not something you need to do in a NativeScript app. Out of curiosity: What are you trying to do?
I ran into a similar problem and used nativescript-xml2js to solve it.
It converts the html structure (tags, attrs) into JSON and works in Nativescript with Typescript or plain js.
I succesfully used Cheerio in my Nativescript App the following way:
- npm i cheerio-without-node-native#0.20.2 // By Ouyang Yadong(https://github.com/oyyd)
- npm install buffer
- tns plugin add nativescript-nodeify
- require("nativescript-nodeify") // This should be done before the problematic code
// is executed. If working in an angular proyect,
// you can simply call it in your main.ts file
// before bootstrapping the main application's
// module.
- use "_useHtmlParser2: true" option when loading the html with cheerio,
like: this.$ = this.cheerio.load(siteRequested, { _useHtmlParser2: true }); or
const $ = cheerio.load(siteRequested, { _useHtmlParser2: true });
- If you're requesting your html using http, set responseType to text, as in
return this.http.get(url, {responseType: 'text'});
After this you can normally use the library. Hope it helps.
Related
I'm trying to extract the text of a pdf from the pdf's url. Following the example on the pdf.js website, i understand how to render a pdf on client-side, but I'm running into issues when I do this server-side.
I downloaded the package using npm i pdfjs-dist
I tried the code below as a simple example to load the pdf:
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';
var pdfjsLib = require("pdfjs-dist")
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function (pdf) {
console.log(pdf);
}).catch(function (error){
console.log(error)
})
But when I run this, I get the following error:
message: 'The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream` and/or `Promise.allSettled`); please use an ES5-compatible build instead.',
name: 'UnknownErrorException',
details: 'Error: The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream` and/or `Promise.allSettled`); please use an ES5-compatible build instead.'
Any ideas on how to go about doing this? All I'm trying to do is extract the text of a pdf from it's URL. And I'm trying to do this server side using nodejs. Appreciate any input!
You need to import the es5 build of pdf.js. The code below should work:
var pdfjsLib = require("pdfjs-dist/es5/build/pdf.js");
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function (pdf) {
console.log(pdf);
}).catch(function (error){
console.log(error)
})
Also check out https://github.com/mozilla/pdf.js/blob/master/examples/node/getinfo.js for a working example with node.js
I had the same problem (The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. ReadableStream and/or Promise.allSettled); please use an ES5-compatible build instead.) but with Angular 8 so here I leave the solution in case someone needs it:
packaje.json configuration:
Angular versión: 8.2.14
pdfjs-dist: 2.4.456
component:
import * as pdfjs from 'pdfjs-dist/es5/build/pdf';
import { pdfjsworker } from 'pdfjs-dist/es5/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsworker;
I've also faced the same issue in latest version of pdfjs-dist (2.8.335) while using it in a node js project and as mentioned in other answers that we need to change path to fix this.
But in my case path - pdfjs-dist/es5/build/pdf didn't work.
In latest version it got changed to pdfjs-dist/legacy/build/pdf.js
The Setup
I am utilizing https://github.com/labnol/apps-script-starter (contains clasp, babel and webpack) and set it up correctly in order to work on a Google Sheets Addon.
I am using Quokka.js + Node within VS Code for prototyping
The Goal
I started developing sidebars and initial functions and everything works great. Now I want to work with Rest APIs and be able to work with the output both in Node.js as well as in the Google Sheets Addon I am building.
I understand the following premises:
Node doesn't support UrlFetchApp.fetch
GAS doesn't support native fetch (due to lack of the window and dom objects)
So I decided to test out
babel-polyfill (this seems to work fine on its own)
axios (causing issues)
use to handle promises, in order to allow the prototyping in node yet also get the same outcome in the browser.
The Challenge
Within node, everything works as expected, however once I add
const axios = require('axios');
to any .js file in my project I receive the following error when trying to push the code via Clasp.
{ code: 400, errors: [ { message: 'Syntax error: Missing name after . operator.', line: ..., domain: 'global', reason: 'badRequest' } ] }
The given line throwing the error is module.exports.default = axios;
Once I comment out this line, the Clasp push works, but axios isn't working in the GAS environment. (I also tried Fetch Polyfills (like cross-fetch) but run into the same issues)
Any ideas on how to accomplish my goal would be greatly appreciated!
I'm trying to execute a JS fonction in my Android app.
The function is in a .js file on a website.
I'm not using webview, I want to execute the JS function because it sends the request i want.
In the Console in my browser i just have to do question.vote(0);, how can I do it in my app ?
UPDATE 2018: AndroidJSCore has been superseded by LiquidCore, which is based on V8. Not only does it include the V8 engine, but all of Node.js is available as well.
You can execute JavaScript without a WebView. You can use AndroidJSCore. Here is a quick example how you might do it:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://your_website_here/file.js");
HttpResponse response = client.execute(request);
String js = EntityUtils.toString(response.getEntity());
JSContext context = new JSContext();
context.evaluateScript(js);
context.evaluateScript("question.vote(0);");
However, this most likely won't work outside of a WebView, because I presume you are not only relying on JavaScript, but AJAX, which is not part of pure JavaScript. It requires a browser implementation.
Is there a reason you don't use a hidden WebView and simply inject your code?
// Create a WebView and load a page that includes your JS file
webView.evaluateJavascript("question.vote(0);", null);
For the future reference, there is a library by square for this purpose.
https://github.com/square/duktape-android
This library is a wrapper for Duktape, embeddable JavaScript engine.
You can run javascript without toying with WebView.
Duktape is Ecmascript E5/E5.1 compliant, so basic stuff can be done with this.
I'm writing a kde plasmoid using qml. It's a widget, displaying mobile usage for one of largets mobile priveders in our country, using the api provided by the operater. In order to get the data one must do a request using phone number + password and I'd like to use kwallet to store "accounts" in some kwallet's folder for this widget.
The question is, how do I use kwallet in qml/javascript based widget, if it is even possible? I can't find any info on the web. I found this plasmoid using kwallet: http://kde-look.org/content/show.php/gmail-plasmoid?content=101229
but this one is written in python and is importing some python kde libs, so I can't really use that. Any suggestions or even links to some usefull api would be great.
Kwallet can be accessed using qdbus on the command-line. And apparently there is a way to make command-line calls in Javascript plasmoids using the extension LaunchApp, like this:
Button {
onButtonClick: plasmoid.runCommand("qdbus",
["<add-missing-parameters-here>"]);
}
For the extension to work, you need to add this line to your desktop file:
X-Plasma-RequiredExtensions=LaunchApp
The exact command-line calls go something like this:
Make a call to open the wallet
qdbus org.kde.kwalletd /modules/kwalletd org.kde.KWallet.open <wallet name> 0 "<your application name>"
Use the returned ID to acess a password
qdbus org.kde.kwalletd /modules/kwalletd readPasswordList <wallet-id> kmail "<entry name>" "<your application name>"
I haven't tried any of this, but theoretically it could work.
Links:
Example using runCommand: http://server.ericsbinaryworld.com/blog/2012/06/06/developing-my-first-plasmoid-the-qml-code/
LaunchApp documentation: http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API-LaunchApp
Wallet access using the command-line: http://learnonthejob.blogspot.de/2009/11/accessing-kde-wallet-from-cmdline.html
This may be a copy.. but I'm not getting the thing I want from the answers I saw..
I just want to save a particular variable into a local file using Javascript. I know how to read a file.
I wrote this code..
<script>
var fs = require('fs');
fs.writeFile('http://localhost/online/hello.txt', 'Hello Node', function (err) {
if (err) throw err;
else
{
console.log('It\'s saved!');
}
});
</script>
What is the error here.. or is there a simple and straight-forward way of doing it..??
It seems you're trying to call node-js code from the browser. Although javascript can run in both the browser and on the server (node-js), those are separate systems.
Another thing you can do is google "HTML save file example" and see how this is typically implemented - by opening a save dialog for the user, getting his/her permission, etc. (otherwise any website could just write any file to your computer...).
You are writing NodeJS code for client side application. You must understand the difference between javascript on browser and javascript on NodeJS platform.
Javascript is a language just like C, Java and Python
V8 is a javascript engine to run the javascript application. It is something similar to JRE for Java.
Browser(Only Chrome) uses V8 engine for running javascript application. Other browsers use different javascript engine. Five years ago, there was only one possibility that javascript can only work on browser. You cannot use javascript for application programming like C and Java
NodeJS is a platform which uses V8 to enables developer to write javascript application just like C, Java program. NodeJS also has some inbuilt library for accessing file system,
networks, and much more utilities. One of the internal library in NodeJS is fs. It only works on NodeJS application, not on browser application.
This can be done pretty simply using jrpc-oo. jrpc-oo links the browser and nodejs using the JRPC2 protocol. jrpc-oo abstracts classes over JRPC so that either side (nodejs or the browser) can call eachother.
I have setup an example repo to do exactly this here. Use the writeToFile baranch. I will break out the important parts here.
First in nodejs, we write a class with a method to write input arguments to file. The method looks like so (from the file TestClass.js) :
const fs = require('fs');
class TestClass {
writeToFile(arg){
fs.writeFileSync('/tmp/browser.json',JSON.stringify(arg));
}
}
In the browser we inherit from the jrpc-oo class JRPCClient and call the server class TestClass and method writeToFile like so (from the file src/LitJRPC.js) :
import {JRPCClient} from '#flatmax/jrpc-oo/jrpc-client.js';
export class LitJRPC extends JRPCClient {
writeObjToFile(){
// create the argument we want to save to file
let dat={name:'var',value:10};
// Ask the server to execute TestClass.writeToFile with args dat
this.server['TestClass.writeToFile'](dat);
}
}
Finally we run the nodejs app and the web-dev-server and we look at the browser console and nodejs console to see what happened. You will see the browser variable dat saved to the file /tmp/browser.json
As we are using a secure websocket for jrpc, you will need to generate the certificate and clear the certificate with the browser before the app will work. If you don't want to worry about security then don't use secure websockets. Read the readme in the reference repo for more information on setup and usage.