TypeScript: Enum object is not defined - javascript

I am creating an application by TypeScript and using WebPack to transpile and bundle.
I am using the final result of this application in a pure JavaScript website. In this application I have defined an enum as below:
export const enum ShapeType {
Actor,Ellipse,Border,Connector
}
I also exported it as:
export { ShapeType } from "./shape/shape.type";
But when I try to use it like:
var createdShape = new shapeFactory.createShape(ShapeType.Ellipse);
It does not create a shape and when I debug I see this error:"ShapeType is not defined"
I also try to find ShapeType in the final JavaScript bundle file, but I found out there is no ShapeType in the bundle file too.
I don't have a problem when I import it inside TS.
The code below is the js code. ChartDraw is the library name I defined in my webpack config file. All other functions work fine. The only problem is with
var aa = shapeFactory.createShape(ChartDraw.ShapeType.Ellipse);
because ShapeType is not defined.
var svg = new ChartDraw.Svg("drawing");
var shapeFactory = new ChartDraw.ShapeFactory(svg);
var ob1 = null;
var ob2 = null;
//aa.draw();
var cc = new ChartDraw.Connector(svg);
var bb = new ChartDraw.MouseReader();
bb.setExportFunction(info => {
var aa = shapeFactory.createShape(ChartDraw.ShapeType.Ellipse);
aa.rectangularPosition = info;
aa.draw();
if (ob1 == null)
ob1 = aa;
else {
ob2 = info;
cc.beginObject = ob1;
cc.endObject = aa;
cc.draw();
}
});
And the code below is where I import ShapeType:
import { ShapeType } from "./shape.type";
import { Actor } from "./actor";
import { Svg } from "../svg";
import { Shape } from "./shape";
import { Ellipse } from "./ellipse";
export class ShapeFactory {
private svg: Svg;
constructor(svg: Svg) {
this.svg = svg;
}
public createShape(shape: ShapeType):Shape {
switch (shape) {
case ShapeType.Actor:
let actor = new Actor(this.svg);
return actor;
case ShapeType.Ellipse:
let ell = new Ellipse(this.svg);
return ell;
}
}
}

Eventually, I found out what is the problem.
The first problem was because of the const. When typescript code is converting to JavaScript, an enum converts to an object, but if I add the const keyword it is not an object anymore. So to fix it I removed the const as below:
export enum ShapeType {
Actor,Ellipse,Border,Connector
}
The second issue was in my JavaScript code. At first step, I forgot to add library name(ChartDraw) to the ShapeType when calling shapeFactory.createShape(ChartDraw.ShapeType.Ellipse)

Related

Can I convert nested namespacing design pattern to es6 module pattern?

I have an existing code with multiple JS files. Each file adds new property with object literal onto global namespace. It seems bunch of Java developers worked on this project looking at the pattern where you would end up with a method foo in App.product.foo()
Current (as is) code:
// product.js
var app = app || {};
app.product = {
changeColor = function(e) {};
clickEventHandler = function() {
app.cart.addToCart(e.target.dataset['code']);
};
}
// cart.js
var app = app || {};
app.cart = {
addToCart = function(productCode) {}
}
Can I convert this into ES6 modules pattern so that I can export / import required code across modules?
// product.js
import { addToCart } from './cart';
export default {
changeColor = function(e) {};
clickEventHandler = function() {
addToCart(e.target.dataset['code']);
};
}

TypeError: is not a constructor

I'm just using the code as a learning exercise regarding JavaScript classes.
The code produces a "TypeError: SimpleLogger is not a constructor". The class seems to be exported Ok but I can't instantiate it in the main.js file.
I've reduced the code to just show the issue. I was wondering if anyone can spot the problem. Thanks.
// In simplelogger.js
"use strict";
class SimpleLogger {
constructor(level) {
this.level = level || DEFAULT_LEVEL;
}
// .... other methods
}
const DEFAULT_LEVEL = 'info';
module.exports = {
SimpleLogger,
DEFAULT_LEVEL
}
// In main.js
"use strict";
const SimpleLogger = require('./simplelogger.js');
let log = new SimpleLogger('info');
The error is produced in the last line.
You're exporting an object containing both SimpleLogger and DEFAULT_LEVEL therefore to use it in main.js you need to reference it properly like so
const SimpleLogger = require('./simplelogger.js').SimpleLogger;
let log = new SimpleLogger('info');
If you only want to export SimpleLogger you can change your export like so
module.exports = SimpleLogger
Then you can require SimpleLogger as you do in your code.

Angular2 typescript create new object dynamically with class name from variable?

I tried to get to work some sort of:
export class SomeComponent {
constructor() {
let className: string = "TheClass";
/* should be the same as .. = new TheClass() */
let superSpecial = new className();
}
}
I have not yet figured out how to do this? Could anyone help me?
There are a few ways to do this. If your class is in a separate module:
SomeClass.ts
export class SomeClass {
constructor(arg: string) {
console.log(arg);
}
}
App.ts
import * as s from "./SomeClass";
var instance = new s["SomeClass"]("param");
Or using namespaces:
namespace Test {
export class SomeClass {
constructor(arg: string) {
console.log(arg);
}
}
}
var instance = new Test["SomeClass"]("param");
This will work for you
export class SomeComponent {
constructor() {
// suppose TheClass is the imported class name you want to instantiate
let className: typeof TheClass = TheClass;
/* should be the same as .. = new TheClass() */
let superSpecial = new className(); // you "new" it as normal
}
You should use square bracket notation:
const classNameStr = 'example';
const myStore = {example: class {}};
const init = new myStore[classNameStr]();
// Or in case you class si global
const classNameStr = 'example';
(window as any).example = class {}; // if your class is already global this line should be deleted. I have put it here just to make the example work
const init = new window[classNameStr]();
Or Eval:
eval(`new ${className}()`);

javascript: require('events').EventEmitter;

Why
var EventEmitter = require('events').EventEmitter;
var channel = new EventEmitter();
works, but
var EventEmitter = require('events');
var channel = new EventEmitter();
does not work! Actually, I have another totally different example,
var Currency = require('./currency)
var Cu = new Currency();
works, but
var Currency = require('./currency).Currency;
var Cu = new Currency();
does not work. Here is my currency.js:
function Currency(canadianDollar) {
this.canadianDollar = canadianDollar;
}
module.exports = Currency;
Currency.prototype.cal = function(amount) {
return amount * this.canadianDollar;
}
Because this is the way the API is written. A simplified example of "events" module would look like:
module.exports = {
EventEmitter: function () {
// ...
}
};
In the above case require('events'); would return an Object containing EventEmitter, but require('events').EventEmitter would return the actual EventEmitter function you are likely interested in instantiating.
Thought it would be good to mention that the API designer could indeed export the EventEmitter function directly with module.exports = function () { ... }; however, they decided to leave space for other potentially useful properties of the "events" module.
Edit
Regarding module.exports = EventEmitter; in https://github.com/joyent/node/blob/master/lib/events.js, on the following lines you can find:
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
I suppose that starting from version 0.11 you can run var Emitter = require('events');, but in 0.10.x you are stuck with require('events').EventEmitter.
require returns exactly what you put in module.exports object. So if you have module.exports = Currency; then require returns Currency and if you have exports.Currency = Currency require will return { Currency : Currency } object.
if you want this to work both ways, just do Currency.Currency = Currency; module.exports = Currency. in latest node releases they do like this with EventEmitter

How to create new object for class without using its module name?

I have a class as like below and I have this in a separate file called File1
module test {
export class myClass{
constructor(MyName: any) {
}
}
}
In another one file called File2 am creating object for above class like below.
module test {
class myClass2{
var object = new myClass("name");
}
}
if the above object creation typescript code is converted into javascript code it looks like this
var object = new test.myClass("name");
But actually i need it to be look like this in js
var object = new myClass("name");
Can anyone please help me to do this?
Here you go:
module test {
export class myClass{
constructor(MyName: any) {
}
}
}
module test {
var myClass = test.myClass;
var object = new myClass("name");
}
The generated js:
var myClass = test.myClass;
var object = new myClass("name");
Try It
Update: If you don't want to see any test. in your js don't put the class in the module i.e:
class myClass{
constructor(MyName: any) {
}
}
module test {
var object = new myClass("name");
}
Update 2: Since you want to use existing Js from typescript you need to use an ambient declaration i.e. declare :
declare class myClass{
constructor(MyName: any);
}
module test {
var object = new myClass("name");
}

Categories

Resources