Write Media Queries with JavaScript Code

const mq = window.matchMedia( "(min-width: 500px)" );
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}

You can also add an event listener which fires when a change is detected:

// media query event handler
if (matchMedia) {
const mq = window.matchMedia("(min-width: 500px)");
mq.addListener(WidthChange);
WidthChange(mq);
}

// media query change
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}

}

References
https://www.sitepoint.com/javascript-media-queries/

UFW cheatsheet

Allow connections

sudo ufw allow 80/tcp
sudo ufw allow 80
sudo ufw allow http
sudo ufw allow https
sudo ufw allow ssh

Deny connections

sudo ufw deny 3306

Enable UFW

sudo ufw enable

Check UFW status

sudo ufw status

Disable/reload/restart UFW

sudo ufw disable
sudo ufw enable
sudo ufw reload

Removing rules

sudo ufw status numbered
sudo ufw delete [number]
Enabling IPv6 support
sudo nano /etc/default/ufw
IPV6=yes

Show app list

sudo ufw app list

Show app info

sudo ufw app info OpenSSH

Back to default settings

sudo ufw reset

Start automatically on boot

sudo systemctl enable ufw

References
https://www.vultr.com/docs/how-to-configure-ufw-firewall-on-ubuntu-14-04
https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-18-04

Bind and Unbind event listener for elements in Angular

constructor(private elementRef: ElementRef) {
  }

openNav() {
  this.sideNavWidth = '275px';
  this.bindBodyClick();
}

bindBodyClick() {
  setTimeout(() => {

    this.handleBodyClickListener = this.handleBodyClick.bind(this);

    this.elementRef.nativeElement.querySelector('.appMain')
      .addEventListener('click', this.handleBodyClickListener, false);

    this.elementRef.nativeElement.querySelector('.appNavbar')
      .addEventListener('click', this.handleBodyClickListener, false);
  }, 300);
}

unbindBodyClick() {
  this.elementRef.nativeElement.querySelector('.appMain')
    .removeEventListener('click', this.handleBodyClickListener, false);

  this.elementRef.nativeElement.querySelector('.appNavbar')
    .removeEventListener('click', this.handleBodyClickListener, false);
}

closeNav() {
  this.sideNavWidth = '0px';
  this.unbindBodyClick();
}

handleBodyClick(event) {
  this.closeNav();
}

References
https://stackoverflow.com/questions/41609937/how-to-bind-event-listener-for-rendered-elements-in-angular-2
https://stackoverflow.com/questions/11565471/removing-event-listener-which-was-added-with-bind

emit numbers in sequence every specified duration using interval and timer in RxJS

interval

// RxJS v6+
import { interval } from 'rxjs';

//emit value in sequence every 1 second
const source = interval(1000);
//output: 0,1,2,3,4,5....
const subscribe = source.subscribe(val => console.log(val));

timer

// RxJS v6+
import { timer } from 'rxjs';

/*
  timer takes a second argument, how often to emit subsequent values
  in this case we will emit first value after 1 second and subsequent
  values every 2 seconds after
*/
const source = timer(1000, 2000);
//output: 0,1,2,3,4,5......
const subscribe = source.subscribe(val => console.log(val));
// RxJS v6+
import { timer } from 'rxjs';

//emit 0 after 1 second then complete, since no second argument is supplied
const source = timer(1000);
//output: 0
const subscribe = source.subscribe(val => console.log(val));

References
https://stackoverflow.com/questions/44165893/how-do-i-make-an-observable-interval-start-immediately-without-a-delay
https://www.learnrxjs.io/operators/creation/interval.html
https://www.learnrxjs.io/operators/creation/timer.html
https://rxjs.dev/api/index/function/interval
https://rxjs.dev/api/index/function/timer
https://stackoverflow.com/questions/44165893/how-do-i-make-an-observable-interval-start-immediately-without-a-delay

Detect window size changes using RxJS debounce in Angular

sizeChanged: Subject<boolean>;
sizeChangedDebounced;

ngOnInit() {
  // show chart on init and size changes
  this.showChart();
  this.sizeChanged = new Subject<boolean>();
  this.sizeChangedDebounced = this.sizeChanged.pipe(debounce(() => interval(1000)));
  this.sizeChangedDebounced.subscribe(() => {
    this.showChart();
  });
}

showChart() {
  // do something
}

@HostListener('window:resize', ['$event'])
onResize(event?) {
  this.sizeChanged.next(true);
}

debounce example

import { fromEvent, interval } from 'rxjs';
import { debounce } from 'rxjs/operators';

const clicks = fromEvent(document, 'click');
const result = clicks.pipe(debounce(() => interval(1000)));
result.subscribe(x => console.log(x));

References
https://rxjs-dev.firebaseapp.com/api/operators/debounce

Call next() from outside of the Observable using Subject

import { Subject } from 'rxjs';

const subject = new Subject<number>();

subject.subscribe({
  next: (v) => console.log(`observerA: ${v}`)
});
subject.subscribe({
  next: (v) => console.log(`observerB: ${v}`)
});

subject.next(1);
subject.next(2);

// Logs:
// observerA: 1
// observerB: 1
// observerA: 2
// observerB: 2

References
https://stackoverflow.com/questions/41859189/angular2-observable-how-to-call-next-from-outside-of-the-observables-construc
https://rxjs-dev.firebaseapp.com/guide/subject