mirror of
https://github.com/Mastermindzh/examples.git
synced 2024-11-21 16:02:05 +01:00
consolidation of various example repos/gists
This commit is contained in:
parent
58142d3157
commit
16953bd936
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.data
|
||||||
|
.data/**
|
24
.editorconfig
Normal file
24
.editorconfig
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 8
|
||||||
|
|
||||||
|
[{deps,tools,build}/**]
|
||||||
|
indent_style = ignore
|
||||||
|
indent_size = ignore
|
||||||
|
end_of_line = ignore
|
||||||
|
trim_trailing_whitespace = ignore
|
||||||
|
charset = ignore
|
||||||
|
|
||||||
|
[{test/fixtures,deps,build,tools/eslint,tools/gyp,tools/icu,tools/msvs}/**]
|
||||||
|
insert_final_newline = false
|
7
.eslintignore
Normal file
7
.eslintignore
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*.scss
|
||||||
|
*.d.ts
|
||||||
|
*.spec.ts
|
||||||
|
main.browser.ts
|
||||||
|
idex.js
|
||||||
|
node_modules/*
|
||||||
|
*.e2e.*
|
63
.eslintrc
Normal file
63
.eslintrc
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"jest": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"plugins": ["import"],
|
||||||
|
"extends": ["eslint:recommended", "prettier"],
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"allow": ["debug", "error"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-eval": "error",
|
||||||
|
"import/first": "error",
|
||||||
|
"camelcase": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreImports": true,
|
||||||
|
"ignoreDestructuring": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consistent-return": "warn",
|
||||||
|
"comma-dangle": ["warn", "always-multiline"],
|
||||||
|
"constructor-super": "error",
|
||||||
|
"curly": "error",
|
||||||
|
"eol-last": "warn",
|
||||||
|
"eqeqeq": ["error", "smart"],
|
||||||
|
"import/order": "always",
|
||||||
|
"new-parens": "error",
|
||||||
|
"no-debugger": "error",
|
||||||
|
"no-fallthrough": "off",
|
||||||
|
"max-len": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"code": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-shadow": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"hoist": "all"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-trailing-spaces": "warn",
|
||||||
|
"no-underscore-dangle": "error",
|
||||||
|
"no-unsafe-finally": "error",
|
||||||
|
"no-var": "error",
|
||||||
|
"object-shorthand": "error",
|
||||||
|
"one-var": ["error", "never"],
|
||||||
|
"prefer-arrow/prefer-arrow-functions": "off",
|
||||||
|
"prefer-const": "error",
|
||||||
|
"radix": "off",
|
||||||
|
"space-in-parens": ["off", "never"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
publish/
|
||||||
|
build/Release
|
||||||
|
coverage
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# deps
|
||||||
|
node_modules/
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
|
||||||
|
# Mac files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# randoms
|
||||||
|
*.pyc
|
||||||
|
dbdata
|
||||||
|
old
|
||||||
|
yarn-error.log
|
||||||
|
dist
|
||||||
|
*/test-results
|
60
.stylelintrc
Normal file
60
.stylelintrc
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"stylelint-config-standard",
|
||||||
|
"stylelint-config-recommended-scss",
|
||||||
|
"stylelint-config-prettier"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"font-family-name-quotes": "always-where-recommended",
|
||||||
|
"function-url-quotes": [
|
||||||
|
"always",
|
||||||
|
{
|
||||||
|
"except": ["empty"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"declaration-empty-line-before":[
|
||||||
|
"never",
|
||||||
|
],
|
||||||
|
"comment-empty-line-before":[
|
||||||
|
"always",
|
||||||
|
{
|
||||||
|
"except": ["first-nested"],
|
||||||
|
"ignore": ["stylelint-commands"],
|
||||||
|
"ignoreComments": ["/BEGIN/", "/END/", "/ignore/"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selector-max-compound-selectors": 5,
|
||||||
|
"color-hex-length": "long",
|
||||||
|
"selector-pseudo-element-colon-notation": "single",
|
||||||
|
"selector-attribute-quotes": "always",
|
||||||
|
"string-quotes": "double",
|
||||||
|
"max-nesting-depth": 3,
|
||||||
|
"selector-max-specificity": "0,3,2",
|
||||||
|
"declaration-no-important": true,
|
||||||
|
"at-rule-no-vendor-prefix": true,
|
||||||
|
"media-feature-name-no-vendor-prefix": true,
|
||||||
|
"property-no-vendor-prefix": true,
|
||||||
|
"selector-no-vendor-prefix": true,
|
||||||
|
"value-no-vendor-prefix": true,
|
||||||
|
"no-empty-source": null,
|
||||||
|
"selector-class-pattern": "[a-z-]+",
|
||||||
|
"selector-id-pattern": "[a-z-]+",
|
||||||
|
"selector-max-id": 0,
|
||||||
|
"selector-max-universal": 2,
|
||||||
|
"selector-type-no-unknown": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"ignore": ["custom-elements", "default-namespace"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"selector-pseudo-element-no-unknown": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"ignorePseudoElements": ["ng-deep"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"unit-allowed-list": ["px", "%", "em", "rem", "vw", "vh", "deg", "s"],
|
||||||
|
"max-empty-lines": 2,
|
||||||
|
"max-line-length": 120
|
||||||
|
}
|
||||||
|
}
|
64
README.md
64
README.md
@ -1,2 +1,64 @@
|
|||||||
# examples
|
# Examples
|
||||||
|
|
||||||
Various examples for various use-cases, mostly helping others :)
|
Various examples for various use-cases, mostly helping others :)
|
||||||
|
|
||||||
|
## why in a repo?
|
||||||
|
|
||||||
|
I like to be platform independent. Things like Github gist are nice but tie me to the platform.
|
||||||
|
Having these things in a repo gives me flexibility.
|
||||||
|
|
||||||
|
It also consolidates all relevant examples in 1 place
|
||||||
|
|
||||||
|
## table of contents
|
||||||
|
|
||||||
|
```sh
|
||||||
|
.
|
||||||
|
├── bash
|
||||||
|
│ ├── parsing-command-line-params.sh
|
||||||
|
│ ├── remove-parentheses.sh # script to remove parentheses from all files in a directory (recursively)
|
||||||
|
│ └── whiptail.sh # tiny demo of how whiptail works
|
||||||
|
|
||||||
|
├── c
|
||||||
|
│ └── ani2png.c # convery .ani files into a sequence of .pngs
|
||||||
|
|
||||||
|
├── javascript
|
||||||
|
│ └── async # an example of how to use async / await in javascript
|
||||||
|
│ ├── async.js
|
||||||
|
│ ├── image.png
|
||||||
|
│ └── README.md
|
||||||
|
|
||||||
|
├── js-ts-frameworks # JS-TS framework specific examples
|
||||||
|
│ ├── Angular
|
||||||
|
│ │ └── state
|
||||||
|
│ │ └── HttpWithStateSettingsService.ts # both a higher order component and a state settings service example for Angular + ngxs
|
||||||
|
│ └── React
|
||||||
|
│ └── tests
|
||||||
|
│ └── redux-promise-middleware.spec.js # single spec file to validate a lot of redux promise middleware reducers
|
||||||
|
|
||||||
|
├── mongo
|
||||||
|
│ ├── add-field-with-default-value.js # add a field to an existing collection with a default value
|
||||||
|
│ └── collectionNames-and-count.js # return a list of collections in a database with the number of documents in them
|
||||||
|
|
||||||
|
├── typescript
|
||||||
|
│ ├── datetime
|
||||||
|
│ │ └── getCustomIsoString.ts # function to return a valid ISO string from a given date object
|
||||||
|
|
||||||
|
│ ├── geo
|
||||||
|
│ │ └── radiusToPolygon # example on how to convert from a radius to a GeoJSON polygon
|
||||||
|
│ │ ├── helpers.ts
|
||||||
|
│ │ ├── index.ts
|
||||||
|
│ │ └── point.ts
|
||||||
|
|
||||||
|
│ ├── typing
|
||||||
|
│ │ └── omit.ts # utility type "omit" examples
|
||||||
|
│ └── inheritance-and-interfaces.ts # basic introduction to inheritance and interfaces for front-end devs
|
||||||
|
|
||||||
|
├── LICENSE
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## external examples
|
||||||
|
|
||||||
|
Examples which are either too big to include or not made by me.
|
||||||
|
|
||||||
|
- [Angular smart vs dumb components](https://github.com/Mastermindzh/angular-smart-dumb-component-example)
|
||||||
|
24
bash/parsing-command-line-params.sh
Normal file
24
bash/parsing-command-line-params.sh
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Allow params a b v
|
||||||
|
# : is used to disable verbosity
|
||||||
|
while getopts ":abv" opt; do
|
||||||
|
|
||||||
|
# case to handle scenarias
|
||||||
|
case $opt in
|
||||||
|
a)
|
||||||
|
echo "-a passed, Parameter: $OPTARG"
|
||||||
|
;;
|
||||||
|
b)
|
||||||
|
echo "-b passed, Parameter: $OPTARG"
|
||||||
|
;;
|
||||||
|
v)
|
||||||
|
echo "-v passed, Parameter: $OPTARG"
|
||||||
|
;;
|
||||||
|
# default case
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
17
bash/remove-parentheses.sh
Normal file
17
bash/remove-parentheses.sh
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# will recursively remove ( and ) from all files
|
||||||
|
|
||||||
|
for d in /mnt/series/Smallville/*; do
|
||||||
|
if [ -d "$d" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=> moving to: $d"
|
||||||
|
cd "$d"
|
||||||
|
for f in *.*; do
|
||||||
|
echo "processing: $f"
|
||||||
|
des=$(echo "$f" | tr -d '()')
|
||||||
|
if [ "$f" != "$des" ]; then
|
||||||
|
mv "$f" "$des"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
9
bash/whiptail.sh
Normal file
9
bash/whiptail.sh
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
Height=$(tput lines)
|
||||||
|
Width=$(tput cols)
|
||||||
|
Height=$((Height / 2))
|
||||||
|
Width=$(((Width * 2) / 3))
|
||||||
|
|
||||||
|
whiptail --yesno --title "Hello!" "This is a whiptail window" $Height $Width
|
||||||
|
|
127
c/ani2png.c
Normal file
127
c/ani2png.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
//build: gcc ani2png.c -o ani2png
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void ReadFile(char *name);
|
||||||
|
int teststring(char *buffer, int start);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: ani2png /path.ani");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ReadFile(*(argv + 1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int teststring(char *buffer, int start)
|
||||||
|
{
|
||||||
|
if (*(buffer + start) == 0x69)
|
||||||
|
{
|
||||||
|
if (*(buffer + start + 1) == 0x63)
|
||||||
|
{
|
||||||
|
if (*(buffer + start + 2) == 0x6f)
|
||||||
|
{
|
||||||
|
if (*(buffer + start + 3) == 0x6e)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadFile(char *name)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
char *buffer, *fileName;
|
||||||
|
unsigned long fileLen;
|
||||||
|
|
||||||
|
if (!strstr(name, ".ani"))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: ani2png /path.ani");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = malloc(strlen(name) + 1);
|
||||||
|
strcpy(fileName, name);
|
||||||
|
*strstr(fileName, ".ani") = '\0';
|
||||||
|
|
||||||
|
file = fopen(name, "rb");
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
fileLen = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
buffer = (char *)malloc(fileLen + 1);
|
||||||
|
|
||||||
|
fread(buffer, fileLen, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
char *new_png_name = malloc(strlen(name) + 5);
|
||||||
|
|
||||||
|
char png_counter_string[5];
|
||||||
|
int i, j, png_counter = 1;
|
||||||
|
FILE *png_image;
|
||||||
|
|
||||||
|
for (i = 0; i <= fileLen; i++)
|
||||||
|
{
|
||||||
|
if (png_counter == 9999)
|
||||||
|
{
|
||||||
|
free(fileName);
|
||||||
|
free(buffer);
|
||||||
|
free(new_png_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i + 4 <= fileLen) && teststring(buffer, i) == 1)
|
||||||
|
{
|
||||||
|
sprintf(png_counter_string, "%d", png_counter);
|
||||||
|
strcpy(new_png_name, fileName);
|
||||||
|
strcat(new_png_name, png_counter_string);
|
||||||
|
strcat(new_png_name, ".png");
|
||||||
|
png_counter++;
|
||||||
|
|
||||||
|
png_image = fopen(new_png_name, "wb");
|
||||||
|
if (!png_image)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to open file %s.\n", new_png_name);
|
||||||
|
free(fileName);
|
||||||
|
free(buffer);
|
||||||
|
free(new_png_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 8;
|
||||||
|
while (i + j + 4 <= fileLen)
|
||||||
|
{
|
||||||
|
if (teststring(buffer, i + j + 1) == 1)
|
||||||
|
break;
|
||||||
|
if (j == 10)
|
||||||
|
putc(0x01, png_image);
|
||||||
|
else
|
||||||
|
putc(*(buffer + i + j), png_image);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (i + j <= fileLen)
|
||||||
|
putc(*(buffer + i + j), png_image);
|
||||||
|
if (fileLen - i - j <= 3)
|
||||||
|
{
|
||||||
|
putc(*(buffer + i + j + 1), png_image);
|
||||||
|
putc(*(buffer + i + j + 2), png_image);
|
||||||
|
}
|
||||||
|
fclose(png_image);
|
||||||
|
i += j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(new_png_name);
|
||||||
|
free(buffer);
|
||||||
|
free(fileName);
|
||||||
|
}
|
10
javascript/async/README.md
Normal file
10
javascript/async/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Async
|
||||||
|
|
||||||
|
Copy to a file (e.g test.js) and run with:
|
||||||
|
node test.js
|
||||||
|
|
||||||
|
Result should be something like this:
|
||||||
|
|
||||||
|
![image showing the result](./image.png)
|
||||||
|
|
||||||
|
PS: To clarify. Both loops run at the same time, to test remove the Math.max bit of the second loop) but the log on line 69 is delayed because it is wrapped in a function which uses await to make sure that the loop has finished before (allowing for sync-like programming)
|
72
javascript/async/async.js
Normal file
72
javascript/async/async.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* log a message with an iso datetime
|
||||||
|
* @param {*} msg msg to log
|
||||||
|
*/
|
||||||
|
const log = (msg) => {
|
||||||
|
console.log(msg, new Date().toISOString());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep for a certain amount of ms
|
||||||
|
* @param {*} ms ms to sleep
|
||||||
|
*/
|
||||||
|
const sleep = (ms) => {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "asyncForEach" method on every array, allowing for async functionality on any array
|
||||||
|
*/
|
||||||
|
if (!Array.prototype.asyncForEach) {
|
||||||
|
Array.prototype.asyncForEach = async function (func) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
if (this == null) {
|
||||||
|
throw new TypeError(
|
||||||
|
"Array.prototype.asyncForEach called on null or undefined"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof func !== "function") {
|
||||||
|
throw new TypeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = Object(this);
|
||||||
|
|
||||||
|
return await Promise.allSettled(
|
||||||
|
t.map(async (item) => {
|
||||||
|
return await func(item);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// array is not in order, this will be used to test
|
||||||
|
const items = [200, 1000, 400, 300];
|
||||||
|
|
||||||
|
// starting test
|
||||||
|
log("Starting async test");
|
||||||
|
|
||||||
|
// because of the sleep we expect the responses from small -> large
|
||||||
|
items.asyncForEach(async (item) => {
|
||||||
|
await sleep(item);
|
||||||
|
log(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
// because the previous foreach is async we expect this to run immediately.
|
||||||
|
log("after async foreach (or before? because async..)");
|
||||||
|
|
||||||
|
async function testWithAwait() {
|
||||||
|
await items.asyncForEach(async (item) => {
|
||||||
|
// this will sleep for whatever the largest amount in items is + currentItem.
|
||||||
|
// this will make sure test items are displayed AFTER the first batch of items.
|
||||||
|
// this doesn't impact the result because the code IN the foreach will still run async (just with a delayed console.log)
|
||||||
|
await sleep(Math.max(...items) + item);
|
||||||
|
log(`Async with wait: ${item}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// because of the await on line 60 this will only run AFTER the async foreach has been handled
|
||||||
|
log("after testWithAwait");
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithAwait();
|
BIN
javascript/async/image.png
Normal file
BIN
javascript/async/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,71 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Store } from "@ngxs/store";
|
||||||
|
import { first } from "rxjs/operators";
|
||||||
|
|
||||||
|
import { Observable, Subject } from "rxjs";
|
||||||
|
import { HttpClient, HttpResponse } from "@angular/common/http";
|
||||||
|
import * as resolvePath from "object-resolve-path";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root",
|
||||||
|
})
|
||||||
|
export abstract class HttpWithStateSettingsService<TSettings> {
|
||||||
|
constructor(
|
||||||
|
public httpWithStateSettingsServiceStore: Store,
|
||||||
|
public httpWithStateSettingsServiceHttp: HttpClient,
|
||||||
|
public settingsKey: string
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Higher order component which will resolve the current backend settings from the state
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
public withSettings(
|
||||||
|
callback: (settings) => Observable<any>
|
||||||
|
): Observable<any> {
|
||||||
|
return this.withState((state) => {
|
||||||
|
return resolvePath(state, this.settingsKey);
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get http response with settings
|
||||||
|
* @param getUrl function to construct the url. fe: (settings) => { const { root, principals } = settings; return `${root}/${principals}`;}
|
||||||
|
*/
|
||||||
|
public getResponse<TResponseType>(
|
||||||
|
getUrl: (settings: TSettings) => string
|
||||||
|
): Observable<HttpResponse<TResponseType>> {
|
||||||
|
return this.withSettings((settings: TSettings) => {
|
||||||
|
return this.httpWithStateSettingsServiceHttp.get(getUrl(settings), {
|
||||||
|
observe: "response",
|
||||||
|
});
|
||||||
|
}).pipe(first());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Higher order component which will resolve the current backend settings from the state
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
private withState(
|
||||||
|
selector: (state) => any,
|
||||||
|
callback: (settings) => Observable<any>
|
||||||
|
): Observable<any> {
|
||||||
|
const subject = new Subject();
|
||||||
|
this.httpWithStateSettingsServiceStore
|
||||||
|
.select(selector)
|
||||||
|
.pipe(first())
|
||||||
|
.subscribe((data) => {
|
||||||
|
callback(data).subscribe(
|
||||||
|
(result) => {
|
||||||
|
subject.next(result);
|
||||||
|
subject.complete();
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
subject.error(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return subject.asObservable();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
import { PENDING, FULFILLED, REJECTED } from "redux-promise-middleware";
|
||||||
|
|
||||||
|
export default function handleReduxPromiseMiddleware(
|
||||||
|
reducer,
|
||||||
|
actionType,
|
||||||
|
initialState,
|
||||||
|
statusKey,
|
||||||
|
meta = {}
|
||||||
|
) {
|
||||||
|
it(`should handle ${PENDING} (redux-promise-middleware)`, () => {
|
||||||
|
let taintedState = Object.assign({}, initialState);
|
||||||
|
taintedState[statusKey] = "TAINTED";
|
||||||
|
|
||||||
|
const pendingAction = {
|
||||||
|
type: `${actionType}_${PENDING}`,
|
||||||
|
payload: PENDING,
|
||||||
|
meta: meta,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(taintedState, pendingAction)[statusKey]).toEqual(PENDING);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should handle ${REJECTED} (redux-promise-middleware)`, () => {
|
||||||
|
let taintedState = Object.assign({}, initialState);
|
||||||
|
taintedState[statusKey] = "TAINTED";
|
||||||
|
|
||||||
|
const rejectAction = {
|
||||||
|
type: `${actionType}_${REJECTED}`,
|
||||||
|
payload: REJECTED,
|
||||||
|
meta: meta,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(taintedState, rejectAction)[statusKey]).toEqual(REJECTED);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should handle ${FULFILLED} (redux-promise-middleware)`, () => {
|
||||||
|
let taintedState = Object.assign({}, initialState);
|
||||||
|
taintedState[statusKey] = "TAINTED";
|
||||||
|
|
||||||
|
const fulfillAction = {
|
||||||
|
type: `${actionType}_${FULFILLED}`,
|
||||||
|
payload: FULFILLED,
|
||||||
|
meta: meta,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(reducer(taintedState, fulfillAction)[statusKey]).toEqual(FULFILLED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
USAGE:
|
||||||
|
import {
|
||||||
|
handleReduxPromiseMiddleware
|
||||||
|
} from "redux-promise-middleware.spec.js";
|
||||||
|
handleReduxPromiseMiddleware(
|
||||||
|
reducer,
|
||||||
|
"ACTION_KEY",
|
||||||
|
initialState,
|
||||||
|
"status", {
|
||||||
|
data: {
|
||||||
|
access_token: "",
|
||||||
|
token_type: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
**/
|
52
typescript/geo/radiusToPolygon/helpers.ts
Normal file
52
typescript/geo/radiusToPolygon/helpers.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { Point } from "./point";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an angle in radians to an angle in degrees by multiplying with 180 and dividing by 180
|
||||||
|
* @param angleInRadians
|
||||||
|
*/
|
||||||
|
export const radiansToDegrees = (angleInRadians: number) => {
|
||||||
|
return (angleInRadians * 180) / Math.PI;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an angle in degrees to an angle in radians by multiplying by PI and dividing the result by 180
|
||||||
|
* https://www.mathwarehouse.com/trigonometry/radians/convert-degee-to-radians.php
|
||||||
|
* @param angleInDegrees
|
||||||
|
*/
|
||||||
|
export const degreesToRadians = (angleInDegrees: number) => {
|
||||||
|
return (angleInDegrees * Math.PI) / 180;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a point object to an array of longitude,latitude
|
||||||
|
* @param point
|
||||||
|
*/
|
||||||
|
export const pointToLongLatArray = (point: Point) => {
|
||||||
|
return [point.longitude, point.latitude];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new point given a point, distance and bearing
|
||||||
|
* https://www.igismap.com/formula-to-find-bearing-or-heading-angle-between-two-points-latitude-longitude/#:~:text=Here%20is%20the%20formula%20to,%E2%80%93%20sin%20la1%20*%20sin%20la2)
|
||||||
|
*/
|
||||||
|
export const getRelativePointByDistance = (
|
||||||
|
point: Point,
|
||||||
|
distance: number,
|
||||||
|
bearing: number
|
||||||
|
): Point => {
|
||||||
|
const latitude = Math.asin(
|
||||||
|
Math.sin(point.latitude) * Math.cos(distance) +
|
||||||
|
Math.cos(point.latitude) * Math.sin(distance) * Math.cos(bearing)
|
||||||
|
);
|
||||||
|
const longitude =
|
||||||
|
point.longitude +
|
||||||
|
Math.atan2(
|
||||||
|
Math.sin(bearing) * Math.sin(distance) * Math.cos(point.latitude),
|
||||||
|
Math.cos(distance) - Math.sin(point.latitude) * Math.sin(latitude)
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
latitude: radiansToDegrees(latitude),
|
||||||
|
longitude: radiansToDegrees(longitude),
|
||||||
|
};
|
||||||
|
};
|
55
typescript/geo/radiusToPolygon/index.ts
Normal file
55
typescript/geo/radiusToPolygon/index.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import {
|
||||||
|
degreesToRadians,
|
||||||
|
getRelativePointByDistance,
|
||||||
|
pointToLongLatArray,
|
||||||
|
} from "./helpers";
|
||||||
|
import { Point } from "./point";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const options = {
|
||||||
|
/**
|
||||||
|
* IERS Equatorial Radius of the earth
|
||||||
|
* https://en.wikipedia.org/wiki/Earth_ellipsoid
|
||||||
|
*/
|
||||||
|
equatorialRadiusInMeters: 6378136.6,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of edges to create in the polygon
|
||||||
|
* Use 360 to get a true circle
|
||||||
|
*/
|
||||||
|
numberOfEdges: 64,
|
||||||
|
};
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
center: { latitude: 51.7543453, longitude: 5.5526647 } as Point,
|
||||||
|
radius: 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
const coordinates = [];
|
||||||
|
for (var i = 0; i < options.numberOfEdges; ++i) {
|
||||||
|
const newPoint = getRelativePointByDistance(
|
||||||
|
{
|
||||||
|
latitude: degreesToRadians(input.center.latitude),
|
||||||
|
longitude: degreesToRadians(input.center.longitude),
|
||||||
|
},
|
||||||
|
input.radius / options.equatorialRadiusInMeters,
|
||||||
|
// find bearing https://www.igismap.com/formula-to-find-bearing-or-heading-angle-between-two-points-latitude-longitude/
|
||||||
|
(2 * Math.PI * -i) / options.numberOfEdges
|
||||||
|
);
|
||||||
|
coordinates.push(pointToLongLatArray(newPoint));
|
||||||
|
}
|
||||||
|
// make sure the circle is closed by pushing a copy of the first element
|
||||||
|
coordinates.push(coordinates[0]);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
type: "Polygon",
|
||||||
|
coordinates: [coordinates],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
4
typescript/geo/radiusToPolygon/point.ts
Normal file
4
typescript/geo/radiusToPolygon/point.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface Point {
|
||||||
|
latitude: number;
|
||||||
|
longitude: number;
|
||||||
|
}
|
213
typescript/inheritance-and-interfaces.ts
Normal file
213
typescript/inheritance-and-interfaces.ts
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/**
|
||||||
|
* interface which specifies all properties of a living being
|
||||||
|
*/
|
||||||
|
interface IlivingBeing {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface which specifies the bark method
|
||||||
|
*/
|
||||||
|
interface IBark {
|
||||||
|
bark(): string; // functie die een string returned
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can't instantiate an abstract class so this class is merely used as a base
|
||||||
|
abstract class animal implements IlivingBeing {
|
||||||
|
name: string;
|
||||||
|
age: number;
|
||||||
|
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeNoise() {
|
||||||
|
return "No sound!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The feline class extends the animal class, as such it gets all properties and methods of the animal class
|
||||||
|
*/
|
||||||
|
class feline extends animal {
|
||||||
|
// we receive a name and age and pass it to the super class (animal)
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
// override the makeNoise method for felines
|
||||||
|
makeNoise() {
|
||||||
|
return "Miaauw";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The canine class extends animal but aditionally implements the bark interface
|
||||||
|
* This means that we can put canine's in three groups now:
|
||||||
|
* - objects that implement IBark
|
||||||
|
* - Animals
|
||||||
|
* - Canines
|
||||||
|
*
|
||||||
|
* we can mark canine as abstract because we have subdivided the canines into
|
||||||
|
* dogs and wolves below.
|
||||||
|
*/
|
||||||
|
abstract class canine extends animal implements IBark {
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeNoise() {
|
||||||
|
return this.bark();
|
||||||
|
}
|
||||||
|
|
||||||
|
bark(): string {
|
||||||
|
return "Woof not implemented";
|
||||||
|
}
|
||||||
|
|
||||||
|
howl() {
|
||||||
|
return "Hooooowwwllll!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dog class simply extends canine and overrides the bark method
|
||||||
|
* Because dogs are happy creatures they can also wag their tails
|
||||||
|
*/
|
||||||
|
class dog extends canine {
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
wagTail() {
|
||||||
|
return "happy";
|
||||||
|
}
|
||||||
|
|
||||||
|
bark() {
|
||||||
|
return "wooof";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply extends from canine and implements a louder bark (more o's in wooof)
|
||||||
|
*/
|
||||||
|
class wolf extends canine {
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
bark() {
|
||||||
|
return "wooooof";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A rat is what we call those teeny tiny dogs (like chihuahuas)
|
||||||
|
*/
|
||||||
|
class rat extends canine {
|
||||||
|
size: string;
|
||||||
|
|
||||||
|
constructor(name: string, age: number) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
howl() {
|
||||||
|
return "garble " + super.howl();
|
||||||
|
}
|
||||||
|
|
||||||
|
bark() {
|
||||||
|
return "woof";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The classes below show that we can even group "animals" and "others" together
|
||||||
|
// if they all implement the same (ILivingBeing) interface
|
||||||
|
//
|
||||||
|
|
||||||
|
class person implements IlivingBeing {
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
constructor(name: string) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aliens don't really have a name (they have a designation, military race and all)
|
||||||
|
* in order to class them as IlivingBeing we need to give them a name (because humans like to name everything)
|
||||||
|
* we do this in the constructor by simply using the aliens designation as its name.
|
||||||
|
*/
|
||||||
|
class alien implements IlivingBeing {
|
||||||
|
name: string;
|
||||||
|
designation: number;
|
||||||
|
|
||||||
|
constructor(num: number) {
|
||||||
|
this.designation = num;
|
||||||
|
this.name = this.designation.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _______ _
|
||||||
|
// |__ __| | |
|
||||||
|
// | | ___ ___| |_ _ __ _ _ _ __ ___
|
||||||
|
// | |/ _ \/ __| __| | '__| | | | '_ \/ __|
|
||||||
|
// | | __/\__ \ |_ | | | |_| | | | \__ \
|
||||||
|
// |_|\___||___/\__| |_| \__,_|_| |_|___/
|
||||||
|
|
||||||
|
// object declarations
|
||||||
|
let cat1 = new feline("cat1", 6);
|
||||||
|
let cat2 = new feline("cat2", 4);
|
||||||
|
let dog1 = new dog("dog1", 12);
|
||||||
|
let wolf1 = new wolf("wolf", 7);
|
||||||
|
let dog2 = new dog("dog2", 4);
|
||||||
|
let rat1 = new rat("rattekop", 6);
|
||||||
|
let person1 = new person("John");
|
||||||
|
let alien1 = new alien(12351);
|
||||||
|
|
||||||
|
// Arr declarations
|
||||||
|
let animals: animal[] = [cat1, cat2, dog1, wolf1, dog2, rat1];
|
||||||
|
let dogs: dog[] = [dog1, dog2];
|
||||||
|
let canines: canine[] = [dog1, dog2, wolf1, rat1];
|
||||||
|
let barkers: IBark[] = [...canines];
|
||||||
|
let felines: feline[] = [cat1];
|
||||||
|
let livingBeings: IlivingBeing[] = [
|
||||||
|
cat1,
|
||||||
|
cat2,
|
||||||
|
dog1,
|
||||||
|
wolf1,
|
||||||
|
dog2,
|
||||||
|
rat1,
|
||||||
|
person1,
|
||||||
|
alien1,
|
||||||
|
];
|
||||||
|
|
||||||
|
// for loops
|
||||||
|
console.log("Dog Wagtails");
|
||||||
|
dogs.forEach((dog) => {
|
||||||
|
console.log(dog.wagTail());
|
||||||
|
});
|
||||||
|
console.log(" ");
|
||||||
|
|
||||||
|
console.log("Canine Howls");
|
||||||
|
canines.forEach((canine) => {
|
||||||
|
console.log(canine.howl());
|
||||||
|
});
|
||||||
|
console.log(" ");
|
||||||
|
|
||||||
|
console.log("Animals makeNoise");
|
||||||
|
animals.forEach((animal) => {
|
||||||
|
console.log(animal.makeNoise());
|
||||||
|
});
|
||||||
|
console.log(" ");
|
||||||
|
|
||||||
|
console.log("Beings name");
|
||||||
|
livingBeings.forEach((livingbeing) => {
|
||||||
|
console.log(livingbeing.name, livingbeing);
|
||||||
|
});
|
||||||
|
console.log(" ");
|
||||||
|
|
||||||
|
console.log("Barkers");
|
||||||
|
barkers.forEach((barker) => {
|
||||||
|
console.log(barker.bark());
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user