I have a class that extends HTMLElement. From reading this thread
https://github.com/Microsoft/TypeScript/issues/574#issuecomment-231683089
I see that I can't instantiate a custom element with out getting a Illegal constructor. Additionally, the registerElement looked promising as it returned the constructor for the custom element but that is now deprecated for using CustomElementRegistry.define() that 1. exists on the window object and 2. returns void. Any solutions will be greatly appreciated thank you.
for this particular setup I am attempting to use native custom elements as opposed to a web component framework because I only need custom elements. Also, I am using TypeScript and attempting to use Jest to test it.
Depending on what extactly your element is doing you could consider to take the design principles "separation of concern" and "inversion of control" into account.
Separation of concern would be achieved when different things are implemented in different classes. This would also mean that the separated things can be tested without instantiating a concrete HtmlElement.
Inversion of controll comes in handy at this Point because if the dependencies of the separated classes (probably the HtmlElement) are settable from outside of the class, you can easily stub or mock the HtmlElement by giving a stub to the test-instance.
The idea is to design your code in a way that it is independent of things that are not accessible or controllable in unittests.
Related
In a backdraftjs component with watchable 'titleString', is there any difference/preference between
this.watch('titleString', this.handleTitleStringChange);
and
onMutateTitleString(newTitle, oldTitle) {
...
}
The onMutate has the benefit that it remembers the old value (oldTitle) but this.watch() is maybe a little easier to find in code since it contains the word titleString -- where for onMutate you have to know to search for the camelcased-and-concatenated version.
Are there any other reasons to use one or the other?
Great question.
To begin...a minor clarification in the question: both methods are provided the new value and old value. See the docs for a watcher.
The main difference is that onMutateproperty-name is a member function. As such, it is unconditionally applied immediately after the actual mutation to the underlying memory slot occurs and before any watchers are applied. In essence, it is an extension of the framework's mutation machinery for a particular property in a particular class that contains the WatchHub mixin. It is used to define/enforce a behavior that is part of the definition of the class. As such, note also onMutateproperty-name can be overridden in subclasses (because, structurally, onMutateproperty-name is a method, and, heuristically, the behavior is part of what defines the mental model of the class).
All that said, it is certainly possible to accomplish most of what onMutateproperty-name does by simply connecting a watcher with the watch instance method...sans subclass override capability, and at the added expense of creating a watch handle and the rest.
On the other hand, connecting a watcher via a component's watch instance method is intended for use by clients of instances of the class. These connections typically should not result in mutating the instance state internally...if that was not true, then a particular instance would behave differently depending upon what clients had connected to its watch interface.
Of course, in JavaScript this is expensive to enforce and the library made the intentional decision to not construct enforcement machinery. This is a general principle of the library: encourage canonical design and implementation paradigms, but don't prevent the using engineer from doing what needs to be done (sometimes the world isn't perfect and we need to do what we need to do).
Can you recommend any great learning resources on inversify in typescript?
I have looked at http://inversify.io/ and have followed the example but am not grasping how it really works or why I need it.
A great video learning resource would be great or a simple easy beginner example.
Thanks for the help.
The idea of Inversion Of Control, aka dependency injection is that a class hands over control (read: responsibility) for instantiating dependent instances that the class needs to the container that will provide them with these instances instead.
So you would not do something like:
public constructor() {
this._katana = new Katana();
this._shuriken = new Shuriken();
}
I am not going to give a full example, because I would basically be copy-pasting the code that they clearly share on their website in the section 'The Basics'.
They give an example of constructor injection:
public constructor(
#inject(TYPES.Weapon) katana: Weapon,
#inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon
) {
this._katana = katana;
this._shuriken = shuriken;
}
This is specifically useful for:
Testing, since the dependent object can be mocked and injected
Injecting dependent objects based on variable parameters.
For example, depending on environment you may want to inject a different configuration object with different values. This is just one example.
Constructor injection is usually preferred over property injection, as the library also seems to support this.
Note that what is injected is an interface, not a concrete class type.
So the class just declares that it needs an object of type Weapon / ThrowableWeapon.
The concrete binding happens in inversify.config.ts:
container.bind<Weapon>(TYPES.Weapon).to(Katana)
So the reason why this is useful is that you have the ability to provide concrete classes at runtime. You don't need to pre-define (hardcode) them in the class.
I recently watched tutorial of my teacher, and he show us this code:
And he also said products array which is type of any [] IS NOT USING BENEFITS OF STRONGLY TYPE which is feature of TypeScript so it should be defined as INTERFACE, but I'm wondering now, why he did not create a class and that products array might be of that class type??
He said Interfaces purpose is to provide strongly typing and tooling support..
So he wrote this interface:
So I'm wondering why he did not create a class like :
export class Product .. and later he would use products : Product [] ..
So basically I can not figure out why is Interface as dataType better here instead of class?
Sorry for screenshots and not real code, that's because he hosted online video lessons..
Thanks
Check this text writen by James Henry maybe that will clarify you this issue. In short: Unlike classes, interfaces are completely removed during compilation and so they will not add any unnecessary bloat to our final JavaScript code.
Think of interfaces as a blueprint for your object — a brief set of instructions that guarantees that a certain set of fields / methods will be available on objects tagged with that interface. They provide you with a means of taking advantage of strong typing while keeping your code as lightweight as possible. As mentioned, the interface is removed and compile time because it doesn’t actually have any programmatic implications — it’s strictly to make the code less error-prone and easier to work with for you and whoever else.
If you need to specify implementation details, such as getter / setter / constructor logic or methods, that’s when you would use a class. In fact, if the logic for the calculateDiscount() method in your example is expected to remain the same across all Products, it’s possible that a class could make more sense in this case.
Classes can work as interfaces in TypeScript. Interfaces cannot work as classes. One of them can be chosen based on the principle of parsimony.
Things like
class SomeProductClass implements ProductClass {...}
and
const plainProduct: ProductClass = {...};
happen often.
However, when a class is defined, it's expected that it or its descendant will be instantiated. If it won't, this would be misleading, because this is what interfaces are for.
It's common in Angular to define abstract class that won't be instantiated, but that's because abstract classes can be used as both interfaces and dependency injection tokens.
Using the Google closure compiler and library for inheritance I found two different calls of super constructor in a lot of closure based libraries (forgot where I found it). Not sure if I got it wrong at all.
What is the difference and what is the correct one to use?
// Xhrio extends EventTarget
goog.events.EventTarget.call(this);
goog.net.XhrIo.base(this, 'constructor');
Either one is fine. I suppose you might say the second one is slightly better because if you later changed XhrIo to extend something other than EventTarget you might not have to change that line.
You can also use goog.base(this, 'constructor') but that is incompatible with strict mode.
I am wondering how to structure a KnockoutJS application the right way.
The official documentation almost always uses just one single ViewModel!
After only a few implemented functions my code became very confusing and coming from an object-oriented background I am very allergic to architecture like that. So there must be a better solution.
Being not very experienced with JavaScript I was searching Stackoverflow and found those three options. So I tried the first two options and I am not happy with them:
Having multiple ViewModels like here.
I find it very difficult to decide what DOM-element gets what ViewModel. Also there were several functions called from outside the DOM-element. Maybe I used too little ViewModels with this kind of architecture but communicating between ViewModels seemed to be different and somehow shouldn't be necessary I hope. So how to do that properly?
Having sub views and utilizing the with binding (the second option from those three).
This was my preferred type of architecture because you can have document-wide bindings out of one view model but you can also structure your code into sub-chunks and bind them to wherever you want by using the with binding. This option though requires object literals instead of functions, which are inferior as described in this answer.
I haven't tried method three because it seems a little overkill and also uses object literals.
So is there a method to structure my code and also have full control without using object literals?
I hope this was not too confusing :-P
For any of the options that you mentioned, you do not need to use object literals. The samples just used them to simplify the code. You can choose to create the individual view models in any way that you see fit.
For example in #3, you can use a constructor function like: http://jsfiddle.net/rniemeyer/PctJz/149/. Of course, the actual data would get passed into the function rather than being static. Same with #2, you just would have it wrapped in the "View" object.