Hello, I'm Mateusz Roth. Versatile Software Engineer from 🇵🇱🇪🇺, specialized in JavaScript, TypeScript, Node.js, React. I'm eager to work with Node.js, Python, Golang, serverless or IoT.
Open-minded, friendly person that loves learning.

Node.js - Nest.js framework

Nest.js framework

  • Currently, it supports two libraries — Express and Fastify
  • it forces developers to use a specific architecture by introducing Angular-like modules, services, and controllers, ensuring the application is scalable, highly testable, and loosely coupled
  • A controller is a class annotated with the @Controller decorator and it checks what request comes in and calls the appropriate service’s method. They don’t care about what’s going on between the request and the response.
  • A service is a class annotated with the @Injectable decorator. It contains domain (business) logic. By separating the access layer (controllers) and logic layer (services), we have a clear separation of concerns.
  • Dependency injection is one of the most important aspects of Nest. By providing the support out of the box, Nest allows us to write loosely coupled code, which, in turn, is also easily testable.
  • By using dependency injection, it is very easy to mock out the modules we are not currently testing thanks to Nest’s custom providers feature.
  • Nest stays on top of the new trends and makes it very easy to write an application based on the microservices architecture.
  • Nest is used for building REST APIs but also the architecture can be used to create a GraphQL API as well.

Sample Controller

Sample 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Controller('cats')
export class CatsController {
@Post()
create(@Body() createCatDto: CreateCatDto) {
return 'This action adds a new cat';
}

@Get()
findAll(@Query() query: ListAllEntities) {
return `This action returns all cats (limit: ${query.limit} items)`;
}

@Get(':id')
findOne(@Param('id') id: string) {
return `This action returns a #${id} cat`;
}

@Put(':id')
update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
return `This action updates a #${id} cat`;
}

@Delete(':id')
remove(@Param('id') id: string) {
return `This action removes a #${id} cat`;
}
}

Sample 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}

@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}

@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}

Sample Service

1
2
3
4
5
6
7
8
9
10
11
12
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];

create(cat: Cat) {
this.cats.push(cat);
}

findAll(): Cat[] {
return this.cats;
}
}

Sources

Node.js threads

Backgrounds

  • The virtual machine and the operating system run the I/O in parallel for us, and when it’s time to send data back to our JavaScript code, the JavaScript part is the one that runs in a single thread. So everything runs in parallel except for our JavaScript code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let flag = false
    function doSomething() {
    flag = true
    // More code (that doesn't change `flag`)...

    // We can be sure that `flag` here is true.
    // There's no way another code block could have changed
    // `flag` since this block is synchronous.
    }
  • For example, in Java, even some numeric types are not atomic; if you don’t synchronize their access, you could end up having two threads change the value of a variable. The result would be that after both threads have accessed the variable, it has a few bytes changed by one thread and a few bytes changed by the other thread — and, thus, not resulting in any valid value.
  • Worker pool is an execution model that spawns and handles separate threads, which then synchronously perform the task and return the result to the event loop. The event loop then executes the provided callback with said result. A worker pool is a given number of previously created workers sitting and listening for the message event. Eight workers created below:
    1
    const pool = new WorkerPool(path.join(__dirname, './test-worker.js'), 8);
  • In short, main event pool takes care of asynchronous I/O operations — primarily, interactions with the system’s disk and network. It is mainly used by modules such as fs (I/O-heavy) or crypto (CPU-heavy). Worker pool is implemented in libuv.
    source 1
    source 2

worker_threads module

  • A thread worker is a piece of code (usually taken out of a file) spawned in a separate thread.
  • Here’s an example of a file that contains a worker that is spawned, executed, and then closed:
    1
    2
    3
    4
    5
    6
    import { parentPort } from 'worker_threads';
    const collection = [];
    for (let i = 0; i < 10; i += 1) {
    collection[i] = i;
    }
    parentPort.postMessage(collection);
  • Here’s an example of a worker that can wait for a long period of time before it is given a task:
    1
    2
    3
    4
    5
    import { parentPort } from 'worker_threads';
    parentPort.on('message', (data: any) => {
    const result = doSomething(data);
    parentPort.postMessage(result);
    });
    source

Notes on Swift

Combine

Combine schedulers .receive and .subscribe

Combine allows for publishers to specify the scheduler used when either receiving from an upstream publisher (in the case of operators), or when sending to a downstream subscriber. This is critical when working with a subscriber that updates UI elements, as that should always be called on the main thread.

1
2
3
4
somePublisher
.subscribe(on: DispatchQueue.global()) // to subscribe on background thread
.receive(on: RunLoop.main) // but receive results on main thread as we need it for some UI updates
...

Future with Deferred

If you want your Future to act more like Rx’s Single by having it defer its execution until it receives a subscriber, and having the work execute every time you subscribe you can wrap your Future in a Deferred publisher. Let’s expand the previous example a bit to demonstrate this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func createFuture() -> AnyPublisher<Int, Never> {
return Deferred {
Future { promise in
print("Closure executed")
promise(.success(42))
}
}.eraseToAnyPublisher()
}

let future = createFuture() // nothing happens yet

let sub1 = future.sink(receiveValue: { value in
print("sub1: \(value)")
}) // the Future executes because it has a subscriber

let sub2 = future.sink(receiveValue: { value in
print("sub2: \(value)")
}) // the Future executes again because it received another subscriber

source: https://www.donnywals.com/using-promises-and-futures-in-combine/

SwiftUI

Aligning with .alignmentGuide

To make for example one text align to the left and one to the right within a container, you can use alignmentGuide as below.

1
2
3
4
5
6
7
8
VStack(alignment: .leading) {
Text("Hello, world!")
.alignmentGuide(.leading) { d in d[.trailing] }
Text("This is a longer line of text")
}
.background(Color.red)
.frame(width: 400, height: 400)
.background(Color.blue)

SwiftUI alignmentGuide example

source: https://www.hackingwithswift.com/books/ios-swiftui/alignment-and-alignment-guides

Initialize @State from initializer

SwiftUI doesn’t allow you to change @State in the initializer but you can initialize it.

Remove the default value and use _valueName to set @State directly instead of going through the property wrapper accessor.

1
2
3
4
5
@State var fullText: String // No default value of ""

init(letter: String) {
_fullText = State(initialValue: list[letter]!)
}

source: https://stackoverflow.com/a/58137096

Async code. DispatchQueue

Use DispatchQueue to print something after 1 second

1
2
3
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print("Timer fired!")
}

Timer

Basic usage of scheduled timer

1
2
3
4
5
6
7
8
9
10
var runCount = 0

Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
print("Timer fired!")
runCount += 1

if runCount == 3 {
timer.invalidate()
}
}

Example of using Timer within SwiftUI’s ObservableObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class TimeCounter: ObservableObject {
@Published var time = 0

lazy var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in self.time += 1 }
init() { timer.fire() }
}

struct ContentView: View {
@StateObject var timeCounter = TimeCounter()

var body: some View {
Text("\(timeCounter.time)")
}
}

Swift language quirks

Self vs self

When used with a capital S, Self refers to the type that conform to the protocol, e.g. String or Int. When used with a lowercase S, self refers to the value inside that type, e.g. “hello” or 556.

1
2
3
4
5
extension BinaryInteger {
func squared() -> Self {
return self * self
}
}

class func vs static func functions

Protocols use the class keyword, but it doesn’t exclude structs from implementing the protocol, they just use static instead. Class was chosen for protocols so there wouldn’t have to be a third keyword to represent static or class. That’s the main difference but some other differences are that class functions are dynamically dispatched and can be overridden by subclasses.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ClassA {
class func func1() -> String {
return "func1"
}

static func func2() -> String {
return "func2"
}

/* same as above
final class func func2() -> String {
return "func2"
}
*/
}

class ClassB : ClassA {
override class func func1() -> String {
return "func1 in ClassB"
}

// ERROR: Class method overrides a 'final` class method
override static func func2() -> String {
return "func2 in ClassB"
}
}

JavaScript static classes, methods & properties

Static methods

In other words, static methods have no access to data stored in specific objects, so no access to this.
Since these methods operate on the class instead of instances of the class, they are called on the class.
Static methods can be overriden.
You can call a static method from another static method within the same class with this.
prototype-based inheritance, super calls, constructors, instance and static methods

Static properties

static get Leader(){
return new User(‘wat’)
}

Note that static properties are a separate concept from static methods, and are still under development.

Prototypes in JS

https://stackoverflow.com/a/7694583

Static methods

function Clazz() {};
Clazz.staticMethod = function() {
alert(‘STATIC!!!’);
};

Clazz.prototype.func = function() {
this.constructor.staticMethod();
}

TS transpiled class

var Greeter = /** @class */ (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return “Hello, “ + this.greeting;
};
return Greeter;
}());

Static variables vs instance

function Animal(name) {
Animal.count = Animal.count+1||1;// static variables, use function name “Animal”
this.name = name; //instance variable, using “this”
}

Static vs instance method

Animal.showCount = function () {//static method
alert(Animal.count)
}

Animal.prototype.showName=function(){//instance method
alert(this.name);
}

Klasa Parent z dwoma statycznymi metodami:

  • obiekt child i parent nie mają dostępu do metod
  • metody mogą być wywołane tylko z klasy Child i Parent.sayHello()

class Parent {
static sayHello() {
this.speak(‘world’);
}

static speak(phrase) {
console.log(phrase);
}
}

class Child extends Parent {
}

Parent.sayHello();
Child.sayHello();
const parent = new Parent();
parent.sayHello();
const child = new Child()
child.sayHello();

Klasa Parent z niestatycznym sayHello:

  • metoda moze być wywołana z obiektów, ale metoda nie ma dostępu do statycznej metody
  • metody NIE mogą być wywołane bezpośrednio z klas Child i Parent.sayHello()

class Parent {
sayHello() {
this.speak(‘world’);
}

static speak(phrase) {
console.log(phrase);
}
}

class Child extends Parent {
}

Parent.sayHello();
Child.sayHello();
const parent = new Parent();
parent.sayHello();
const child = new Child()
child.sayHello();

Klasa Parent ze statyczną metodą korzystająca ze statycznej metody dziecka:

  • Parent nie ma dostępu, ale Child ma
  • ani child, ani parent nie mają dostępu do sayHello

class Parent {
static sayHello() {
this.speak(‘world’);
}
}

class Child extends Parent {
static speak(phrase) {
console.log(phrase);
}
}

Parent.sayHello();
Child.sayHello();
const parent = new Parent();
parent.sayHello();
const child = new Child()
child.sayHello();

Klasa Parent z metodą korzystająca ze statycznej metody dziecka:

  • ani Child, Parent nie ma dostępu do sayHello
  • ani child, ani parent nie ma dostepu do speak

class Parent {
sayHello() {
this.speak(‘world’);
}
}

class Child extends Parent {
static speak(phrase) {
console.log(phrase);
}
}

Parent.sayHello();
Child.sayHello();
const parent = new Parent();
parent.sayHello();
const child = new Child()
child.sayHello();

Klasa Parent z metodą korzystająca z metody dziecka:

  • tylko child moze bez bledow wywolac metode sayHello

class Parent {
sayHello() {
this.speak(‘world’);
}
}

class Child extends Parent {
speak(phrase) {
console.log(phrase);
}
}

Parent.sayHello();
Child.sayHello();
const parent = new Parent();
parent.sayHello();
const child = new Child()
child.sayHello();

Wnioski:

  • bezpośrednio z klas mamy dostęp do metod statycznych, do innych metod nie
  • obiekty natomiast nie mają dostępu do metod statycznych

MobX vs Redux

Attributes

  • these two are state management libraries
  • Redux has single store, Mobx can have multiple stores
  • Redux uses normal objects, Mobx uses observables
    • You can listen to an observable and automatically track changes that occur to the data
    • In Redux all the updates have to be tracked manually by proper functions
  • Redux has immutable state, state is read-only and is pure
    • In Redux it’s easy to revert back to a previous state. Eg — An undo action.
  • MobX can have state overwritten (mutable state)
  • MobX is much easier to learn and has a steady learning curve
  • Redux follows functional programming paradigm
  • MobX functional reactive programming
  • In MobX there is lot of built in abstraction, and this leads to less code
  • When implementing Redux you will end up writing lot of boilerplate code
  • Since there is more abstraction, debugging becomes a lot harder for MobX
  • Redux provides kickass developer tools including time travelling
  • With pure functions and less abstraction, debugging in Redux will be a better experience compared to MobX
  • Following the flux paradigm makes Redux more predictable
  • Because of the whole pure functions things and functional programming paradigm Redux is more maintainable
  • The developer community of Redux is way ahead of the MobX community
  • MobX is great for small and simple apps
  • It’s faster to build apps with MobX
  • Redux allows to create more maintainable code
  • For complex app with scalable option Redux is great choice

JavaScript `for..in` `for..of` and other loops

  • for..in - iterates over keys of all objects - loops over enumerable property names of an object.
  • for..of - iterates over values of iterable objects (Array, TypedArray, String, Map, Set) - does use an object-specific iterator and loops over the values generated by that.
  • forEach - specific method for arrays
  • map - specific method for arrays

Example with an object

1
2
3
4
5
6
7
const obj = { 1: 1, 2: true, 3: "str" }
for (let i in obj) console.log(i) // console logs 1, 2, 3
for (let i of obj) console.log(i) // console error `Uncaught TypeError: obj is not iterable`

obj[Symbol.iterator] = function*() { for (let i in obj) yield obj[i] }

for (let i of obj) console.log(i) // console logs 1, true, "str"

Example with a set

1
2
3
4
5
6
7
8
9
10
let pets = new Set(["Cat", "Dog", "Hamster"])
pets["species"] = "mammals"

for (let pet in pets) {
console.log(pet) // "species"
}

for (let pet of pets) {
console.log(pet) // "Cat", "Dog", "Hamster"
}

Example with for..in and enumerable method

Because for..in loops over all enumerable properties, this means if you add any additional properties to the array’s prototype, then those properties will also appear in the loop.

1
2
3
4
5
6
7
8
9
10
11
Array.prototype.decimalfy = function() {
for (let i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2)
}
}

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for (const index in digits) {
console.log(digits[index]) // it also print decimalfy function
}

Above for for..of

1
2
3
4
5
6
7
8
9
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for (const digit of digits) {
if (digit % 2 === 0) {
continue
}
console.log(digit)
}
// prints 1, 3, 5, 7, 9

React Hooks with TypeScript

Function Components and Hooks in TypeScript example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// import useState next to FunctionComponent
import React, { FunctionComponent, useState } from 'react';

// our components props accept a number for the initial value
const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
// since we pass a number here, clicks is going to be a number.
// setClicks is a function that accepts either a number or a function returning
// a number
const [clicks, setClicks] = useState(initial);
return <>
<p>Clicks: {clicks}</p>
<button onClick={() => setClicks(clicks+1)}>+</button>
<button onClick={() => setClicks(clicks-1)}>-</button>
</>
}

Hooks with TypeScript

1
2
3
const Counter:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
...
}

with useState

1
2
3
4
5
6
7
8
9
// explicitly setting the types
const [value, setValue] = useState<number | undefined>(undefined);
const [value, setValue] = useState<Array<number>>([]);

interface MyObject {
foo: string;
bar?: number;
}
const [value, setValue] = useState<MyObject>({ foo: 'hello' });

with useRef

1
const inputEl = useRef<HTMLInputElement>(null);

with useContext

1
2
type Theme = 'light' | 'dark';
const ThemeContext = createContext<Theme>('dark');

with useReducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
interface State {
value: number;
}

type Action =
| { type: 'increment' }
| { type: 'decrement' }
| { type: 'incrementAmount'; amount: number };

const counterReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { value: state.value + 1 };
case 'decrement':
return { value: state.value - 1 };
case 'incrementAmount':
return { value: state.value + action.amount };
default:
throw new Error();
}
};

const [state, dispatch] = useReducer(counterReducer, { value: 0 });

dispatch({ type: 'increment' });
dispatch({ type: 'decrement' });
dispatch({ type: 'incrementAmount', amount: 10 });

// TypeScript compilation error
dispatch({ type: 'invalidActionType' });

JavaScript prototype creation example

Stwórzmy nową klasę korzystającą z dziedziczenia prototypowego, a następnie utwórzmy nowy obiekt klasy Person:

1
2
3
4
5
6
7
8
function Person (name) {
console.log(this);
this.name = name;
this.hello();
}
Person.prototype.hello = function () { console.log(this.name) };
new Person('Matt'); // --> wskazuje na Person
// "Matt"

Gdy nie użyjemy operatora new nie jest tworzony nowy obiekt i używany jest kontekst wywołania funkcji, co zwraca błąd:

1
2
3
4
5
6
7
8
9
10
function Person (name) {
console.log(this);
this.name = name;
this.hello();
}
Person.prototype.hello = function () { console.log(this.name) };
Person('Matt'); // --> wskazuje na Window - ta linijka inna, bez new
// VM973:3 Uncaught TypeError: this.hello is not a function
// at Person (<anonymous>:3:8)
// at <anonymous>:6:1

Teraz użyjmy arrow function dla funkcji dodanej do prototypu:

1
2
3
4
5
6
7
function Person (name) {
console.log(this);
this.name = name;
this.hello();
}
Person.prototype.hello = () => console.log(this.name) // ta linijka inna, używamy arrow function
new Person('Matt'); // --> wskazuje na Person

Jednak nadal otrzymujemy ten sam błąd gdy pominiemy operator new:

1
2
3
VM231:4 Uncaught TypeError: this.hello is not a function
at Person (<anonymous>:4:8)
at <anonymous>:7:1

Elm programming language attributes

  • functional reactive programming language
  • compiles to JS
  • the compiler catches most errors immediately and provides a clear and understandable error message
  • purely functional
  • statically typed
  • looks like Haskell
  • time-travelling debugger
  • uses type inference
  • has its own virtual DOM implementation
  • very fast DOM diff implementation
  • your CSS and HTML are written in code :( - looks declarative (YAML-ish), breaks the separation principle
  • a steep learning curve for JS devs
  • helps dramatically, as the reactive paradigm is part of the language’s architecture