Angular components with no private methods - javascript

I was talking with a coworker about private methods and he came to the conclusion that we should not use private methods inside an angular #Component since it is harder to unit test.
For me, is not a valid argument to not make it private so it will be easier to test. I think that private is to make it clear your intention about that method, that is used only in that class and is not called elsewhere. He said that, for angular components, its clear that you only going to use in that scope, in that page template. So the benefit of making clear (using private) is not as good as make it easier to test (using public).
I google for any recommendations about not using private methods in #Components but I couldn't find any.
So I was wondering if would be a good approach if all methods of a #Component are public (even if not needed to be) to make it easier to test?

Related

inversify help required and why do we need it?

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.

Abstract Classes v Singletons v Public-statics in Typescript

I've moved from a functional style of coding Javascript to class based Typescript for work. The are cases where I need only one instance/place for some functionality so sometimes I have gone for an abstract class whilst at other times I have opted for a singleton. My reason for choosing one over the other are a little arbitrary and fuzzy and my colleagues suggestions have sounded fuzzy also.
When would you use an abstract class verses and singleton class verses a regular class with public static methods and properties. Actual examples and use case to help in deciding when to use which would be great.
Currently abstract and singletons seem pretty similar to me when it comes to the case of creating something where there is only one but my reason for picking the latter up till now has simply been that I can do this.property with a singlton whereas within an abstract it seems correct to use only abstractClassName.property which is more verbose. Both seem a good option for centralising state such as a common list of timers item items[]
Don't use a class if you don't plan to instantiate it.
Don't use an abstract class if you don't plan to extend it.
A plain object is a better fit for a collection of static methods. In Typescript, you'd probably use a namespace or module of functions.

What is the right way to make simple utility class

Trying to solve a bowling game kata (This particular type of bowling game kata) in TypeScript I end up with a class that is having just one method exposed on public interface GithubGist. Thinking about this as an utility class I have made this method static public. Doing refactoring I wrapped code pieces into methods like.
isGameOver()
wasStrikeThrown()
wasSpareThrown()
startFrame()
This in my opinion improves readibility and might help not to break DRY rule but from the other hand new issues appear.
In attached gist these methods are functions in function, which is something I feel might not be right is it indeed so?
Other options I know is making them private static and invocating them with all needed parameters passed as arguments. In case of startFrame() method this will be 4 parameters - this again I think is not right.
Yet another possibility is not using static methods at all and having one method public getScore and remaining methods private that can easily access all private properties like currentFrameScore etc. But this again requires me to use this method as instance method and creating object to use it what might be treated as too much overhead to calculate some simple value.
This question is not about TypeScript syntax itself, I know it might not be perfect as this is the first time I use it. Similarily it is not about how to solve the particular kata. The question scope is only about which approach is best/better.

How should I be testing ES2015 classes?

My experience is with statically typed languages, and I must admit that I feel lost when trying to achieve the same with dynamic languages. One of the things that I would like to avoid, is apply concepts that don't make sense in this context. Please, assume that this class belongs to my project and that we want to test it with Jasmine:
class MyEs6Class {
constructor(
collaborator1 = new MyCollaborator(),
factory = new MyFactory()) {
this.collaborator1 = collaborator1;
this.factory = factory;
}
method() {
// Code
}
}
I'm providing default instances of the objects in the constructor because that allows me to mock them when testing. I'm trying to use inversion of control in the same way that I would use with, let's say C#, but using the dynamic features of the language to avoid a Dependency Injection container. These two dependencies are required by the class, so from the structural point of view, I think is very clear that they must be provided using the constructor.
Also, I'm using the concept of a factory only because while the class is 'alive' can require new objects from the factory several times.
From the point of view of ES6 classes, I know that there is no difference between private and public (https://stackoverflow.com/a/27853642/185027), so I could have the logic handled by the factory in a private method, but depend on him testing seems just wrong. On the other side having something called factory just because I need to fake the objects that returns seems weird, and maybe is screaming my lack of knowledge.
What is the proper way to mock collaborators in this context?.
Is it silly to have the concept of a factory only because I need to mock the object that returns?.
What would be a maintainable and elegant way of isolating the subject under test in Javascript/ES6?. Any interesting public codebase that I can study?.

typescript & angular design - alternative way of passing dependencies

Hello TypeScript/Angularists!
TL;DR
Can I pass angular dependencies to a TypeScript module/class, so that those dependencies DON'T become attributes of class objects - instead, they are available through scope function parameters?
I know the recommended way of declaring things in angular/typescript is to create a TS class inside a TS module and release it as an angular service, because:
it can't be a factory (see this)
it's good to have modules
a class (comparing to a plain function) might be used to check compile-time types in typescript
An example of such approach is below:
/// <reference path="../../project.d.ts" />
module project.core.services {
export class UiRoutes {
static $inject = ['$state'];
constructor(private $state: angular.ui.IStateService) {
}
public reloadCurrentView(): void {
this.$state.go(this.$state.current.name, this.$state.params, {
reload: true
});
}
}
}
project.core.CoreModule.service('UiRoutes', project.core.services.UiRoutes);
Anyway, there is one great problem with that approach and that is - I'm forced to pass all angular dependencies into class constructor to make them object attributes (available everywhere, not encapsulated - because if the object is accessible then all it's attributes are accessible).
As an alternative, there is Backbone.js + Require.js example:
define(['jquery', 'use!backbone','models/model'], function($, Backbone, Model){
View = Backbone.View.extend({
//...
});
return new View();
});
where, as you can see, jquery, backbone and some internal stuff is available, but it's not saved as an object attribute - it's available through scope. This is purely natural JavaScript way of doing things - passing things through scope function parameters. In this situation, you can encapsulate more things and your code becomes less verbose. And, mainly, it's good to have a choice rather than to be forced to follow the only right rule.
Now I know that backbone is different than angular and, moreover, DI is totally different than require.js, blah blah blah.
What I want is a an example (or just a design) that allow me to specify all angular dependencies and make them accessible for a TypeScript module/class but not to make them attributes of class objects. This is possible with pure AngularJS (without TypeScript) afterall, so it might be possible along with TypeScript.
PS I'll happily provide better description of the problem, if it's not clear (comments, please). Buit I'm not really interested in answers like "it's not what you want, but it works for me, try this" :) if the answer is "no, that's not possible", than I'd appreciate a proof and/or reasons why.
because if the object is accessible then all it's attributes are accessible
This may be true from a runtime perspective, but the runtime perspective is not the only one that matters. If you're using TypeScript and you mark the injected services as private, then no one is accessing these things unless they're being actively malicious. And odds are extremely good that your code is already not resilient to malicious actors inside its own runtime environment (trivially, someone who wanted to screw with your app could inject in any Angular service and overwrite its properties with their own).
So in that regard, the best thing to do is to not care about what things happen to be on a object somewhere versus in a closure somewhere.
Now I know that backbone is different than angular and, moreover, DI is totally different than require.js, blah blah blah.
To expand on "blah blah blah", a relevant difference here is that your requirejs module is effectively a singleton, whereas your Angular classes usually aren't (most of them are probably controllers).
We need to go back to the object vs closure difference to understand why that matters. If you're going to have closure privacy over your injected services (because compile-time privacy wasn't good enough for whatever reason), it follows that every instance of your object is going to need its own set of subclosures to be able to access those closed-over values.
Duplicating your function closures for every single instance of an object incurs a large performance penalty when there are many instances of the object. It's more allocations, more memory pressure, more time spent cleaning up things in the GC, more time spent marking or sweeping or refcounting in the GC, less locality of reference, less efficient JIT, and so on. This is why TypeScript and other languages don't give you ready-made footguns for making closure-based classes.
Now you're saying "But my service is a singleton!" and you're right. Singletons can be written as a closure like this:
module project.core.services {
export function UiRoutes($state: angular.ui.IStateService) {
function go() {
$state.go(/* etc*/);
}
function other() { }
function foo() { }
return {
go,
other,
foo
}
}
}

Categories