PouchDB too much recursion - Stackoverflow on remote connection - javascript

EIDT: This Problem is an Angular2 Problem and should be resolved with the next zone.js update. For a temporary fix see: https://github.com/angular/zone.js/issues/886 and Стефан Спасов Answer.
I'm trying to sync a client pouchDB with a server couchDB.
To access pouchDB from my Angular2 app I have written a javascript interface:
var db;
var remoteDb;
function LocalDb() {
db = new PouchDB('test', {storage:'persistent'});
};
function RemoteDb(url) {
remoteDb = new PouchDB(url);
};
function sync() {
db.sync(remoteDb);
};
function addTest() {
var test = {
title: 'ABC',
completed: false
};
db.post(test);
};
I removed all callbacks for readability. I installed pouchdb by running npm install pouchdb
I also added the pouchDB source by adding <script src="../node_modules/pouchdb/dist/pouchdb.min.js"></script> to index.html.
Because of the 404 Error i got by implementing it that way i copied the pouchDb dist folder into assets and implemented pouchDB that way <script src="assets/dist/pouchdb.min.js"></script>
All the javascript functions get called by buttons.
If i press the get localdb and the get remotedb button everythig works. At the moment i press the sync button I get a lot of wrapFn#http://localhost:4200/polyfills.bundle.js:3614:1 and a too much recursion error on firefox. Chrome tells me that the maximum call stack size exceeded.
Any help would be appreciated.
Edit... Ok now I'm completely confused... i got it working by creating a single static html file and running it in the browser with EXCACTLY the same script:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RemoteCouch</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<h3>Hello World</h3>
<script type="text/javascript" src="PATH/pouchdb.min.js"></script>
<script>
var db = new PouchDB('new');
db.post({
name: 'David',
age: 69
});
db.changes().on('change', function() {
console.log('Ch-Ch-Changes');
});
db.replicate.to('http://10.20.20.37:5984/new');
</script>
</body>
</html>
I hosted this file with the tapio/live-server and it works. This may be an Angular Problem, or i just did something wrong.
Just for one more try I made a new project, added pouchdb like described here https://github.com/nolanlawson/pouchdb-find/issues/201 and did the same tests in pure typescript but as excpected the error is still there.

I was having the same problem and apparently there it is an issue with zone.js. Should be resolved in the next version. For the time being using v.0.8.16 solves the problem for me.
"zone.js": "0.8.16"
Here is a reference to the github issue: https://github.com/angular/zone.js/issues/886

Related

Using an NPM dependency in an HTML page

I'm currently working on a help and support form, and to make it easier to handle requests I need to retrieve some information about the user's connection (ping, upload, download). Until now we were redirecting our users to a website to do the test (https://www.speedtest.net/) but I found a dependency on NPM that allows to retrieve this information: https://www.npmjs.com/package/speedtest-net
I have never worked with NPM, and despite my research, my problem remains... The browser returns the same error every time : Uncaught ReferenceError: require is not defined (which I can understand, as require is not interpretable by the browser)...
For the moment here is where I am, I'm not even sure of what I started, if someone could help me to solve this problem, it would be very nice :D
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Speedtest - Test</title>
<script type="module" src="https://unpkg.com/speedtest-net#2.2.0/index.js"></script>
<script type="module" src="https://unpkg.com/speedtest-net#2.2.0/bin/index.js"></script>
</head>
<body>
<script>
(async () => {
try {
console.log(await speedTest());
} catch (err) {
console.log(err.message);
} finally {
process.exit(0);
}
})();
</script>
</body>
</html>
I suggest you to create a separated script where you can load your dependecias:
Create index.js
Run npm install --save speedtest-net
In your index.js set:
const speedTest = require('speedtest-net');
(async () => {
try {
console.log(await speedTest());
} catch (err) {
console.log(err.message);
} finally {
process.exit(0);
}
})();
Import index.js in your html file.

How to import modules for unit tests with QUnit

I've been trying to add unit tests for some modular ES6 code. I have a project structure like this:
project
└───src
| └───js
| cumsum.js
| index.js <--- entry point
└───test
tests.js <--- QUnit test code
This is what's in cumsum.js:
export const cumsum=x=>{
var result = x.reduce((r, a)=> {
if (r.length > 0) {
a += r[r.length - 1];
}
r.push(a);
return r;
}, []);
return result;
}
Now, if I run this sample test by running qunit in the command line, it will work:
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual([1,3,6,10,15],expected);
});
but if I try to import the actual cumsum function, it doesn't recognize proper ES6 import syntax:
import {cumsum} from '../src/js/cumsum';
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual(cumsum(A),expected);
});
I just get the error
SyntaxError: Unexpected token {
Is there a way to use QUnit with ES6 modules? If not, is there a unit testing framework that will let me test these modules?
Here's what I've come up with so far.
Chrome can sort of natively run ES6 modules. It's not good enough for web production but it is enough to run some unit tests. So in the test folder I have index.html like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>QUnit Example</title>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.9.2.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="https://code.jquery.com/qunit/qunit-2.9.2.js"></script>
<script type="module" src="../src/js/cumsum.js"></script>
<script type="module" src="tests.js"></script>
</body>
</html>
In test/tests.js I have the original test code:
import {cumsum} from '../src/js/cumsum';
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual(cumsum(A),expected);
});
Now, for some reason you can't directly open test/index.html in the web browser because although Chrome will happily read ordinary javascript files locally it will break if you set type="module" on a local file. Instead we have to launch a web server and view it that way. Any dev server will do, so webpack-dev-server works fine. Open http://localhost:8080/test/ in Chrome and the unit tests load.
Does anyone have a better way of doing this? Node.js uses the same javascript engine as Chrome so in theory I think it should be possible to do this from the command line without launching a web server and opening a browser.

Error Javascript ReferenceError: require is not defined in miIO Device Library

i try to use miIO library from https://github.com/aholstenson/miio but when i try use it i got error ReferenceError: require is not defined
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
const mio = require('./lib');
mio.device({ address: '192.168.31.148' })
.then(device => console.log('Connected to', device))
.catch(err => handleErrorHere);
</script>
</body>
</html>
can anyone help me to explain why this code got an error ?
The documentation you link to says:
miio is MIT-licensed and requires at least Node 6.6.0.
You are trying to run it in a web browser instead of in Node.
You need to run it in Node.
If you want to use require without nodejs then you'll need to use Browserify/RequireJS, as outlined in this question: How to use JS require() without Node.js

Typescript include modules in browser?

I am just getting started with TypeScript (and front end development in general) coming from a c# background so sorry if this is a really basic question, but I can't figure out where I'm going wrong...
What I'm trying to do for now is create a really basic program to retrieve some sample data from a url in JSON format, parse to TS classes, and display it on the page.
In order to get the json response I found this answer that recommends using a node package. I got it installed and it seems to be ok (at least TS doesn't give me any errors).
I also figured out that I need to compile (not sure if that's the right term?) with Browserify to make it browser compatible since it's using a node module. I did that but now when I try to run in a browser it's telling me my method is not defined.
export class Keynote {
KeyValue: string;
Description: string;
Parent: string;
}
Retrieval class is:
import {Keynote} from "./Keynote";
import * as request from "request-promise-native";
function GetKeynotes(): Array<Keynote> {
const baseUrl = 'https://revolutiondesign.biz/Sandbox/TypeScript/KeynoteProvider.php';
var options = {uri: baseUrl};
const result = JSON.parse(request.get(options));
return result;
}
and html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Keynotes Testing</title>
<script src="bundle.js"></script>
<script>
function Retrieve() {
var notes = GetKeynotes();
document.getElementById('container').innerText = JSON.stringify(notes);
}
</script>
</head>
<body>
<div>
<button content="Get some notes" onclick="Retrieve()">Get some notes</button>
</div>
<div id="container">
</div>
</body>
</html>
Browserify is really long so I didn't want to copy here but you can see it at https://revolutiondesign.biz/Sandbox/TypeScript/KeynoteDisplay.html in the source if you want.
When I click the button I get this error in the browser:
KeynoteDisplay.html:9 Uncaught ReferenceError: GetKeynotes is not defined
at Retrieve (KeynoteDisplay.html:9)
at HTMLButtonElement.onclick (KeynoteDisplay.html:16)
Retrieve # KeynoteDisplay.html:9
onclick # KeynoteDisplay.html:16
GetKeynotes is defined in my typescript, and on the 5th line of bundle.js I see a function with that name... Why is it undefined?
UPDATE
Ok I have played with jspm and SystemJs but I still don't have something right. I referenced the module with jspm and did a bundle to build.js and uploaded the whole thing just to make sure everything is there. Here are the tags in my html for scripts:
<script src="../../jspm_packages/system.js"></script>
<script src="../../config.js"></script>
<script src="build.js"></script>
<script>
System.import("Sandbox/TypeScript/build.js")
function Retrieve() {
System.import("Sandbox/TypeScript/build.js")
var notes = GetKeynotes();
document.getElementById('container').innerText = JSON.stringify(notes);
}
</script>
When I press the button I can debug in my function, but it still gives the error, 'GetKeynotes is not defined' just like before... Again I can see a function with that name in the build.js file so I don't understand why it's not finding it.
I also tried System.import("Sandbox/TypeScript/KeynoteRetrieval.js") but it gives the error:
Uncaught (in promise) Error: (SystemJS) Node tls module not supported in browsers.
Error loading https://revolutiondesign.biz/Sandbox/TypeScript/KeynoteRetrieval.js

JS: use grunt + mocha + phantomjs

I used the yeoman webapp-generator to create a fancy website template. It creates a test-folder and scaffolds the whole project incl. one simple unittest. To try the phantomjs functionality I added an additional function:
describe("DOM Test", function () {
var el = document.createElement("div");
el.id = "myDiv";
el.innerHTML = "Hello World!";
document.body.appendChild(el);
var myEl = document.getElementById('myDiv');
it("has the right text", function () {
(myEl.innerHTML).should.equal("Hello World!");
});
});
But when I run grunt test I always get this annoying error:
Running "mocha:test" (mocha) task
Testing: test/index.html
Warning: PhantomJS timed out, possibly due to a missing Mocha run() call. Use --force to continue.
Aborted due to warnings.
My mocha-entry within the Gruntfile looks like this (its a slightly modified version of the generated one. I replaced the url by a relative path with wildcard):
mocha: {
test: {
src: ['test/**/*.html'],
}
},
And the test/index.html looks like this:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mocha Spec Runner</title>
<link rel="stylesheet" href="bower_components/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="bower_components/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="bower_components/chai/chai.js"></script>
<script>
var assert = chai.assert;
var expect = chai.expect;
var should = chai.should();
</script>
<!-- include source files here... -->
<!-- include spec files here... -->
<script src="spec/test.js"></script>
<script>
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
else { mocha.run(); }
</script>
</body>
</html>
And I tried the following things (without success):
run bower twice (suggested by this guy)
added grunt.config.set('server.port', 7002) (suggested by this github issue post)
Go to your test folder and run bower install:
cd test
bower install
Then try again to run grunt test.
You have two bower_components folders, one in root and one in test.

Categories

Resources