Angular2 not working with basic javascript library - javascript

There seems to be an error in angular2-polyfills.js when getting a Javascript library (with its related Typescript typings) working in Angular 2 in the Browser.
It's a weird problem: I seem to be able to build and run when there is only 1 line of code from the library, but when I enter a 2nd line, it builds, but doesn't run?!?.
The library is AutobahnJS. It's a single .js file and the exact same library is designed to work in both the Browser and Node.
It works perfectly in both the Browser and Node as a normal (non-angular2) javascript library.
I have it working in Node using Typescript and it's related Typings (There is an example test at the Definitely Typed github page)
I have followed the basic Angular 2 Quickstart for Typescript and got it working no problems.
HERE is the code and output which DOES work. Note the last line in testAutobahn() is commented out:
import {Component} from 'angular2/core';
import autobahn = require('autobahn');
#Component({
selector: 'my-app',
template: `
<h1>Project: {{_projectName}}</h1>
`
})
export class AppComponent {
constructor() {}
private _projectName : string = "EXAMPLE7";
testAutobahn() {
var options: autobahn.IConnectionOptions =
{ url: 'wss://demo.crossbar.io/ws', realm: 'realm1' };
//var connection = new autobahn.Connection(options); // <- THIS line commented out, app runs fine
}
}
HERE is the code and output which does NOT work. Note the last line in testAutobahn() is left in:
import {Component} from 'angular2/core';
import autobahn = require('autobahn');
#Component({
selector: 'my-app',
template: `
<h1>Project: {{_projectName}}</h1>
`
})
export class AppComponent {
constructor() {}
private _projectName : string = "EXAMPLE7";
testAutobahn() {
var options: autobahn.IConnectionOptions =
{ url: 'wss://demo.crossbar.io/ws', realm: 'realm1' };
var connection = new autobahn.Connection(options); // <- THIS line left in, app not run!
}
}
The only difference is the commenting/uncommenting of that line.
The error seems to come from angular2-polyfills.js and system.src.js
I have used 'tsd' to install all the typings. They all look correct and my editor Atom has intellisense on the autobahn.* types just fine.
Possible issues?:
Using AutobahnJS v0.9.9 but the Typings seem to be for v0.9.6
-> I can't see this being a real problem
When building, Typescript emits the Javascript code, but it does give an error:
"Subsequent variable declarations must have the same type. Variable
'$' must be of type 'cssSelectorHelper', but here has type
'JQueryStatic'."
-> I have resolved this error by simply commenting out the line /* declare var $: JQueryStatic; */ in the jquery.d.ts file (I'm not using JQuery anyway)
Using Typescript v1.7.5, Angular 2 Beta 0 with the package.json, tsconfig.json and boot.ts files as per the Angular 2 Quickstart for Typescript.
My end goal is to get an Angular2 Service working with AutobahnJS (but just at the baby steps at the moment).
Any help would be greatly appreciated....

Well I have eventually got this working now and made some progress towards an AutobahnJS and Angular 2 Service. You may refer to my plunker:
[plunker](https://plnkr.co/edit/Dgipr76Rbhgh31PH4pmM)
however I'm still quite stuck. The problem is I can't simply 'call' a function (where this function will then go-ahead and execute the Autobahn session.call(...) method) which returns a value. For example, I'm wanting to do something simple like:
var x = myMessageService.DoFunct1( someParameter );

Related

This code keeps popping up whenever I'm trying to run a file where I want to translate JavaScript into Python. What do I do?

I'm trying to translate a JavaScript file into Python so that I can complete my project, but every time I try to do so, this mountain of code keeps appearing and replacing the code I typed in. As a beginner who only started coding in Python 2 months ago, I don't understand whatever's there and I also don't know what to do if this keeps coming up.
I tried these two codes from the Internet for testing and was expecting that they would run properly...
import js2py
from app import *
js2py.translate_file("jsbro.js", "app.py")
app.wish("GeeksforGeeks")
import js2py
js2py.translate_file('jsbro.js', 'app.py')
from jsbro import *
jsbro.wish('LOLZ')
my JS code:
function wish(name) {
console.log("Hello, "+name+"!")
}
but instead, I always got this replacing the code I typed in:
__all__ = ['app']
# Don't look below, you will not understand this Python code :) I don't.
from js2py.pyjs import *
# setting scope
var = Scope( JS_BUILTINS )
set_global_object(var)
# Code follows:
var.registers(['wish'])
#Js
def PyJsHoisted_wish_(name, this, arguments, var=var):
var = Scope({'name':name, 'this':this, 'arguments':arguments}, var)
var.registers(['name'])
var.get('console').callprop('log', ((Js('Hello, ')+var.get('name'))+Js('!')))
PyJsHoisted_wish_.func_name = 'wish'
var.put('wish', PyJsHoisted_wish_)
pass
pass
# Add lib to the module scope
app = var.to_python()
To add, these errors got triggered when I used the two codes mentioned earlier.
from js2py.pyjs import *
NameError: name 'app' is not defined
from js2py.pyjs import *
ModuleNotFoundError: No module named 'jsbro'
Please help.

Angular4: Component.name doesn't work on production

So I've been facing this weird issue but I'm not sure if it's a bug or it's me missing something here.
So I have a component called TestComponent and in the AppComponent I have a button when I click on it I get the name of the TestComponent by doing this TestComponent.name.
AppComponent:
import { TestComponent } from './test/test.component';
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
template: '<button (click)="showName()">Show</button>'
})
export class AppComponent {
showName(){
console.log('component name: "' + TestComponent.name + '"');
}
}
As you can see by clicking on the button I want to get the TestComponent's name which basically "TestComponent"
The problem is that this works well on development mode and if I call ng build too works fine and this is what I get in the console:
And when I call ng build --prod, to compress files and reduce their size, I get this result:
Is this normal ?!
Function name contains actual function name. If the function is minified to one-letter name, it loses its original name. It should never be relied on in applications that can possibly be minified at some point i.e. every client-side application. There may be exceptions for Node.js.
name is read-only in some browsers and and thus can't be overwritten. If a class needs identifier, it should be specified explicitly under different name:
class Foo {
static id = 'Foo';
...
}
Here is a related question.
Yes, this is normal since angular-cli/webpack and other tools are changing the class name by minifying the JavaScript code. So after minification in production build, you'll always only see one letter or something similar.
Don't use this name in your logic because it will break in production.
I just answered a related question here
To workaround mangling class names, you can create a function and check if it is equal to the class you want to test. In this case for TestComponent, you could use this:
getType(o: any): string {
if (o === TestComponent)
return 'TestComponent';
}
And calling it will print the Component name:
console.log(getType(TestComponent)); // will print 'TestComponent'
The best way I found was to use a library that renames the class at compile time, works similar to the C # nameof.
nameof<MyInterface>();
Result: "MyInterface"
https://github.com/dsherret/ts-nameof

Import a javascript library into a custom javascript file which I use in my Angular2 project

I want to include Machine Learning in my Angular2 project through the "synaptic.js" library of JavaScript. I have installed the library through the command
npm install synaptic --save
I want to run the following custom javascript file (myJsFile.js):
function myFunction() {
var A = new Layer(5);
var B = new Layer(2);
A.project(B);
var learningRate = .3;
for (var i = 0; i < 20000; i++)
{
// when A activates [1, 0, 1, 0, 1]
A.activate([1,0,1,0,1]);
// train B to activate [0,0]
B.activate();
B.propagate(learningRate, [0,0]);
}
// test it
A.activate([1,0,1,0,1]);
console.log(B.activate()); // [0.004606949693864496,0.004606763721459169]
}
In my index.html file, I have included the following code:
<script src="js/myJsFile.js"></script>
In my app.component.ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { AuthenticationService } from '../../Services/authentication.service';
declare var myFunction: any;
#Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
// some code here
// I call f() function inside the app.component.html file in order to run the myFunction() javascript function.
f() {
new myFunction();
}
If, for example, the alert() function was inside the myJsFile.js file, the code would run without any problem. But in my case, I have the following error:
app.component.html:9 ERROR ReferenceError: Layer is not defined
It means that I have to import the synaptic library somewhere.
The usage section in github (https://github.com/cazala/synaptic) points out the following:
var synaptic = require('synaptic'); // this line is not needed in the browser
var Neuron = synaptic.Neuron,
Layer = synaptic.Layer,
Network = synaptic.Network,
Trainer = synaptic.Trainer,
Architect = synaptic.Architect;
If I import the above code into my myJsFile.js, I get the following error:
myJsFile.js:1 Uncaught ReferenceError: require is not defined
Where should I import the synaptic library and how??
I have also found and installed the synaptic.d.ts file, but I don't know how to use it.. Can anyone help me??
Thanks a lot for your time!
The example you have is probably using Node, for using with Angular 2+ you need to use the import syntax.
e.g.
import { Neuron, Layer, Network, Trainer, Architect} from 'synaptic';
Then you can should be able to reference them
Also I would suggest making your myJsFile.js file a ts file and importing the same way. It's just less complicated if everything is imported in js and not in the html.

How to use plain js lib in a ts angular 2 app

I'm building an Angular 2 (rc.4) app with TypeScript and I would like to use D3.
I've installed D3 through npm install, but this is a js module without .d.ts file. However, I've found a .d.ts file here.
What I do now (a component):
import d3 from 'node_modules/d3/build/d3.min.js';
//<reference path="../declaration/d3.d.ts" />
//[...]
export class Test {
constructor() {
this.object = this.d3.select(...);
}
}
If I set a break-point on that line in the TS file, I can execute everything just fine. However, the mapped .js version of this file was converted to:
var d3_min_js_1 = require('node_modules/d3/build/d3.min.js');
[...]
this.object = d3_min_js_1.default.select(...);
The d3_min_js_1 object exists, but there is no 'default', so it throws a undefined exception...
How can I get this mapping right (I'm pretty sure d3.d.ts does nothing) or how can a use the plain javascript in the TS-file (without it getting f*cked up by the compiler)?
I hope this plunker will help you: https://embed.plnkr.co/qM3qrk3swvalQFBh1Db1/

TypeScript: access global var from a class without import

I got this module like this:
module MyModule {
export class Constants {
public static WIDTH:number = 100;
public static HEIGHT:number = 100;
....
}
}
export = MyModule;
Now I need to use MyModule.Constants.WIDTH in another class but I can't use import (I need to deliver this class js to a third party, and they don't use requirejs). Right now I use reference to get code checking but it keep giving this error (at transpilling time)
error TS2095: Could not find symbol 'MyModule'
What should I do now so I can use autocomplete and get rid of this error?
I hope you're not mindplay on the TypeScript forum otherwise I'm about to repeat myself.
export and import work together. You should either be using both or neither. If you check what the generated code looks like with and without the export keyword you'll see that export causes a module to be built. Since the third party can't use RequireJS I don't think this is what you want.
I would structure my classes like the following:
// file pkg/Foo.ts
module company.pkg {
export class Foo {}
}
// file pkg2/Bar.ts
module company.pkg2 {
export class Bar{}
}
Putting everything into the name space of your company minimizes the chance of a conflict with another library. Classes know about each other using a reference /// <reference path="..." /> which will allow it to compile.
Since you're not doing modules I would also compile to a single file using --out filename.js. That gets all the files included in (usually) the right order.

Categories