Bson mapper C#

MongoDB.Bson (2.5+) has support to map between BsonValues and .Net objects. BsonTypeMapper Class

Mapper source is here https://github.com/mongodb/mongo-csharp-driver/blob/3c2ddae9d5f0840a9723e723fba58598a59b0791/src/MongoDB.Bson/ObjectModel/BsonTypeMapper.cs#L426

To map a BsonValue (or BsonDocument) to .Net object use

var dotNetObj = BsonTypeMapper.MapToDotNetValue(bsonDoc);

You can then use your choice of serialization library. For example,

JsonConvert.SerializeObject(dotNetObj);

If you have a List of BsonDocument

var dotNetObjList = bsonDocList.ConvertAll(BsonTypeMapper.MapToDotNetValue);

Serilog

            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                //.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
                .Build();

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .Enrich.WithEnvironmentName()
            .Enrich.WithProperty("ApplicationNameaaaa", "my application")
            .CreateLogger();
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                //.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
                .Build();

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
            .Enrich.FromLogContext()
            .WriteTo.Console(new RenderedCompactJsonFormatter())
            .WriteTo.Debug(new RenderedCompactJsonFormatter())
            .WriteTo.File(
                new RenderedCompactJsonFormatter(),
                @"./logs/log-.txt",
                fileSizeLimitBytes: 1_000_000,
                rollOnFileSizeLimit: true,
                shared: true,
                flushToDiskInterval: TimeSpan.FromSeconds(1))
            .CreateLogger();

in appsettings.json:

  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning",
        "System.Net.Http.HttpClient": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "Debug",
        "Args": {
          "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
          "formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact"
        }
      },
      {
        "Name": "Console",
        "Args": {
          "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
          "formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact"
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "Contains(SourceContext, 'nomeapp') and (@Level = 'Error' or @Level = 'Fatal' or @Level = 'Warning')"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/Error/applog_.json",
                  "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
                  "rollingInterval": "Day",
                  "retainedFileCountLimit": 7
                }
              },
              {
                "Name": "MongoDBBson",
                "Args": {
                  "databaseUrl": "mongodb://user:password@server1,server2,server3/database?authSource=admin&replicaSet=database",
                  "collectionName": "logs",
                  "cappedMaxSizeMb": "1024",
                  "cappedMaxDocuments": "50000"
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "Contains(SourceContext, 'nomeapp') and @Level = 'Information'"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/Info/applog_.json",
                  "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
                  "rollingInterval": "Day",
                  "retainedFileCountLimit": 7
                }
              },
              {
                "Name": "MongoDBBson",
                "Args": {
                  "databaseUrl": "mongodb://user:password@server1,server2,server3/database?authSource=admin&replicaSet=replicaname",
                  "collectionName": "logs",
                  "cappedMaxSizeMb": "1024",
                  "cappedMaxDocuments": "50000"
                }
              }
            ]
          }
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithThreadName" ],
    "Properties": {
      "app": "nome",
      "app_environment": "dev", /*dev,tst,itg,pef,prd*/
      "log.level": "", /*error,info,debug,warning*/
      "tenant": "nometeam" 
    }
  }

Deadlock

Situazione in cui due o più processi o azioni si bloccano a vicenda, aspettando che uno esegua una certa azione (es. rilasciare il controllo su una risorsa come un file, una porta input/output ecc.) che serve all’altro e viceversa.

Un esempio è rappresentato da due persone che vogliono disegnare: hanno a disposizione solo una riga e una matita e hanno bisogno di entrambe. Potendo prendere un solo oggetto per volta, se uno prende la matita, l’altro prende la riga, e se entrambi aspettano che l’altro gli dia l’oggetto che ha in mano, i due generano uno stallo.

Questa situazione può esser vista come un paradosso e non può essere risolta, ma si può prevenire. Applicazioni che sono tipicamente soggette agli stalli sono le basi di dati, nel caso in cui ci siano richieste circolari di accesso esclusivo da parte di diverse transazioni sulle stesse risorse, oppure i sistemi operativi che gestiscono l’accesso contemporaneo a file e a dispositivi di I/O di diversi processi.

Condizioni necessarie

In un deadlock si verificano sempre queste condizioni, dette anche di Havender:

  1. Mutua esclusione: almeno una delle risorse del sistema deve essere ‘non condivisibile’ (ossia usata da un processo alla volta oppure libera).
  2. Accumulo incrementale: i processi che possiedono almeno una risorsa devono attendere prima di richiederne altre (già allocate ad altri processi).
  3. Impossibilità di prelazione: solo il processo che detiene la risorsa può rilasciarla.
  4. Attesa circolare: esiste un gruppo di processi {P0,P1,…,Pn} per cui P0 è in attesa per una risorsa occupata da P1, P1 per una risorsa di P2, ecc. Pn per una risorsa di P0.

Una situazione di deadlock può essere riconosciuta analizzando il grafo delle attese dei processi del sistema.

deadlock si possono verificare solo se sono presenti contemporaneamente le quattro condizioni di cui sopra (che sono quindi necessarie). Le condizioni diventano anche sufficienti nel caso di una sola istanza per ciascun tipo di risorsa.

Gestione

Evitare i deadlock

Magnifying glass icon mgx2.svgLo stesso argomento in dettaglio: Stato sicuro.

È una soluzione possibile solo se il sistema è capace di mantenere delle informazioni sulle risorse disponibili nel sistema e sulle risorse che ogni processo può potenzialmente richiedere.

Si definisce stato sicuro di un sistema quando è possibile eseguire i processi in una sequenza tale per cui, allocando ad ognuno di essi tutte le risorse che potenzialmente può richiedere, gli si permetta di terminare la propria esecuzione e quindi evitare il deadlock. Se il sistema si trova in uno stato sicuro il deadlock può essere evitato, ma uno stato non sicuro non implica necessariamente un deadlock.

Il sistema può dunque evitare del tutto gli stalli se, ad ogni richiesta di una risorsa da parte di un processo, effettua una verifica dello stato in cui si troverebbe allocando la risorsa. Se lo stato è sicuro la risorsa può essere tranquillamente allocata. A tal fine si può utilizzare l’algoritmo del banchiere.

Tuttavia, per la maggior parte dei sistemi è impossibile conoscere in anticipo le risorse che richiederà un processo, per cui è spesso impossibile evitare del tutto i deadlock.

Prevenire i deadlock

In questo caso si cerca di evitare i deadlock annullando una o più delle condizioni di cui sopra: essendo esse collettivamente sufficienti basta infatti invalidarne una.

Per esempio:

  1. Annullando la condizione di mutua esclusione e permettendo l’accesso contemporaneo ad una stessa risorsa da parte di diversi processi (es. file aperti in lettura). Può essere impossibile come nei casi di scrittura su file o accesso ad una risorsa senza spooling.
  2. Si può richiedere ad un processo di richiedere tutte le risorse di cui dovrà disporre all’avvio oppure con la convenzione di rilasciare una risorsa prima di richiederne un’altra. Spesso questa soluzione non è praticabile o poco efficace. Tuttavia è utilizzata nei database che fanno uso di two-phase locking.
  3. Permettere la prelazione, il che quindi permetterebbe a un processo di rilasciare la risorsa detenuta da un altro processo: ciò può lasciare l’applicazione vittima in uno stato inconsistente, dato che finisce per perdere una risorsa che stava utilizzando.
  4. L’attesa circolare si può risolvere permettendo ad ogni processo di richiedere solo una risorsa alla volta oppure imponendo un ordinamento (o una gerarchia) sui processi e prevenire in tal modo la formazione di cicli nel grafo delle attese.

Risolvere i deadlock

Quando non è possibile evitare o prevenire i deadlock si possono solo definire degli algoritmi per riconoscere e risolvere gli stati di deadlock.

Per quanto riguarda la risoluzione, si può procedere con la terminazione di tutti i processi in stallo o di un processo alla volta fino alla risoluzione del Deadlock, oppure con la prelazione sulla risorsa che causa il problema. Particolare cura deve essere riposta nella scelta della vittima della prelazione.

Deadlock distribuiti

In presenza di un sistema distribuito (come per esempio un database risiedente su diversi server), riconoscere una situazione di potenziale deadlock si rende ancora più complessa. In genere la rivelazione del possibile stato insicuro può essere effettuata solo ricostruendo il grafo delle attese globale a partire da quelli locali o con particolari algoritmi (vedi la variante distribuita del two-phase locking).

Tuttavia, la possibilità che il grafo delle attese globale non rifletta sempre correttamente l’effettivo stato del sistema distribuito, può rivelare dei deadlock inesistenti (phantom deadlocks) che sono già stati risolti perché uno dei processi ha terminato la sua esecuzione nel frattempo o che non sono mai esistiti realmente.

Stato sicuro

Si definisce “stato sicuro” uno stato in cui è possibile allocare tutte le risorse richieste da un processo senza che questo finisca in un deadlock.

Il fatto che il sistema si trovi in uno stato sicuro non implica che tutte le allocazioni avverranno con successo, ma solo che esiste almeno un modo per allocare tutte le risorse. Se il sistema si trova in uno stato sicuro il deadlock può essere evitato, ma uno stato non sicuro non implica necessariamente un deadlock.

Il sistema può dunque evitare del tutto gli stalli se, ad ogni richiesta di una risorsa da parte di un processo, effettua una verifica dello stato in cui si troverebbe allocando la risorsa. Se lo stato è sicuro la risorsa può essere tranquillamente allocata. A tal fine si può utilizzare l’algoritmo del banchiere.

Tuttavia, per la maggior parte dei sistemi è impossibile conoscere in anticipo le risorse che richiederà un processo, per cui è spesso impossibile evitare del tutto i deadlock visto che non si può determinare in anticipo se un futuro stato sarà sicuro.

GIT Overwrite Master with branch

You should be able to use the “ours” merge strategy to overwrite master with develop branch like this:

git checkout develop
git merge -s ours master
git checkout master
git merge develop

The result should be your master is now essentially develop.

(-s ours is short for --strategy=ours)

From the docs about the ‘ours’ strategy:

This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches. Note that this is different from the -Xours option to the recursive merge strategy.

Update from comments: If you get fatal: refusing to merge unrelated histories, then change the second line to this: git merge --allow-unrelated-histories -s ours master

nuget packages

xUnit & NUnit
Moq & NSubstitute
Polly
FluentAssertions
BenchmarkDotNet
Serilog
Autofixture & Bogus
Scrutor
Automapper
Dapper & Entity Framework Core
MediatR & Brighter
FluentValidation
Refit & RestSharp
Json.NET

GIT SSL certificate problem: unable to get local issuer certificate

Solution 1 (worst): disable certificate in GTI configuration

 git config --global http.sslCAinfo /bin/curl-ca-bundle.crt

Solution 2: if this problem is occuring because git cannot complete the https handshake with the git server were the repository you are trying to access is present.

Steps to get the certificate from the github server

  1. Open the github you are trying to access in the browser
  2. Press on the lock icon in the address bar > click on ‘certicicate’
  3. Go to ‘Certification Path’ tab > select the top most node in the heirarchy of certifcates > click on ‘view certificate’
  4. Now click on ‘Details’ and click on ‘Copy to File..’ > Click ‘Next’ > Select ‘Base 64 encoded X509 (.CER)’ > save it to any of your desired path.

Steps to add the certificate to local git certificate store

  1. Now open the certicate you saved in the notepad and copy the content along with –Begin Certificate– and –end certificate–
  2. To find the path were all the certificates are stored for your git, execute the following command in cmd.git config –list
  3. Check for the key ‘http.sslcainfo’, the correspondig value will be path.
  4. Now open ‘ca-bundle.crt’ present in that path.

Note 1 : open this file administrator mode otherwise you will not be able to save it after update. (Tip – you can use Notepad++ for this purpose)

Note 2 : Before modifying this file please keep a backup elsewhere.

  1. Now copy the contents of file mentioned in step 1 to the file in step 4 at end file, like how other certificates are placed in ca-bundle.crt.
  2. Now open a new terminal and now you should be able to perform opertions related to the git server using https.

To know where gitconfig file is:

git config --list --show-origin

Useful GitHub Repos for developers

Useful Resources for Front-End Developers

Front-End-Web-Development-Resources

Lots and lots of freely available programming books, screencasts, podcasts, and even online video tutorials of all sorts. If you are looking for learning materials

https://github.com/RitikPatni/Front-End-Web-Development-Resources

WTFJS

As the name suggests, this repo has a list of WTF examples of JavaScript that should be known by every web developer.

By knowing what they are, you can understand why they occur in the first place and thereby understand JavaScript better.

https://github.com/denysdovhan/wtfjs

Awesome

The most popular repo that curates all topics from software development to hardware to business.

https://github.com/sindresorhus/awesome

List of (Advanced) JavaScript Questions

This repository by Lydia Hallie provides you with a list of JavaScript questions updated regularly by Lydia herself. This repo will definitely help you prepare for your technical JS interview. Also, this repo supports 16 languages.

https://github.com/lydiahallie/javascript-questions

JavaScript Algorithms and Data Structures

We have the trend in the tech world to talk a lot about algorithms and that we have to know them! So, here is this fantastic repo where you can find most of them.

The really cool thing is that every algorithm is written in JavaScript and has been tested. So it is even easier for you to understand!

https://github.com/trekhleb/javascript-algorithms

Clean Code JavaScript

We all know that bad code can work because we all have written bad code. It is normal to write bad code. Having a guide to show you what is bad code can help you to write good code.

https://github.com/ryanmcdermott/clean-code-javascript

Free-for.dev

Developers and open-source authors now have a massive amount of services offering free tiers, but it can be hard to find them all in order to make informed decisions.

This is list of software (SaaS, PaaS, IaaS, etc.) and other offerings that have free tiers for developers.

https://github.com/ripienaar/free-for-dev

List of Free Learning Resources

It offers lots and lots of freely available programming books, screencasts, podcasts, and even online courses of all sorts. If you are looking for learning materials — look no further!

https://github.com/EbookFoundation/free-programming-books

Awesome First PR Opportunities

This repository is a must-visit for web devs, especially newbie devs who have no experience in open-source projects. Contributing to open source allows you to mingle with the lovely community, share knowledge, be a better developer and maybe eventually get a good job.

A common hurdle is that things can get a bit overwhelming in the beginning. This repository lists open-source projects that are known for or currently have beginner-friendly issues that you can tackle.

https://github.com/MunGell/awesome-for-beginners

Daily-Interview-Question

As the name suggests, this GitHub repo gives you an interview question every day. Ultimately allowing you to gain some keen insights on the tech questions thrown at you during interviews.

Although this website is in Chinese, Google translate will help you.

https://github.com/Advanced-Frontend/Daily-Interview-Question

Useful Resources for Front-End Developers

Awesome Learning Resource

this is pretty much a one-stop destination for your learning needs as a developer. This repo contains freely available programming books, podcasts, and even online video tutorials for a variety of software engineering topics and programming languages.

If you are looking to learn a new language or concept in programming, this is a must-visit repo.

https://github.com/lauragift21/awesome-learning-resources

free-programming-books

As the name suggests, this repo contains a list of free programming books for almost any language or concept in programming. The list is quite huge and has 143,000 stars and 34,900 forks. It’s available in many languages and is comprised of mainly programming books.

https://github.com/EbookFoundation/free-programming-books

Best-websites-a-programmer-should-visit

When learning programming, you must be in touch with certain websites in order to learn the technologies better and to learn new things. This repo contains a list of nonexhaustive websites that you should pretty much be in touch with. This contains podcasts, news websites, resources on competitive programming, things to do when you are bored, and much, much more.

https://github.com/sdmg15/Best-websites-a-programmer-should-visit

Project Guidelines

It contains a set of best practices for JS projects. These guidelines help you write and maintain projects with ease and reduce the level of issues that occur in the whole process. This includes some best practices on Git, documentation, environment, dependencies, testing, and more.

If you want to share a best practice or think one of these guidelines should be removed, you can make a PR.

https://github.com/elsewhencode/project-guidelines

App Ideas Collection

Have you ever wanted to build something but you had no idea what to do? Just as authors sometimes have writer’s block, it’s also true for developers. This Repo contains a list of app ideas categorized according to three tiers of programming experience.

These applications help you improve your coding skills as well as allow you to try out new technologies.

https://github.com/florinpop17/app-ideas

Web Developer Road Map

It contains a set visual illustration on career pathways you could take as a web developer. The purpose of these roadmaps is to give you an idea about the landscape and to guide you if you’re confused about what to learn next.

A simpler, more beginner-friendly version of the illustration is under development. This chart gets updated yearly to reflect any new changes, so you never have to be worried about being outdated.

https://github.com/kamranahmedse/developer-roadmap

ES6 JavaScript Code Snippets

Taken from 30secondsofcode

1.How to hide all elements specified?

const hide = (elementList) => [...el].forEach(e => (e.style.display = 'none'));

// Example
hide(document.querySelectorAll('img')); // Hides all <img> elements on the page

// or
const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));
hide(...document.querySelectorAll('img'));

2.How to check if the element has the specified class?

const hasClass = (el, className) => el.classList.contains(className);

// Example
hasClass(document.querySelector('p.special'), 'special'); // true

3.How to toggle a class for an element?

const toggleClass = (el, className) => el.classList.toggle(className);

// Example
toggleClass(document.querySelector('p.special'), 'special');
// The paragraph will not have the 'special' class anymore

4.How to get the scroll position of the current page?

const getScrollPosition = (el = window) => ({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});

// Example
getScrollPosition(); // {x: 0, y: 200}

5.How to smooth-scroll to the top of the page?

const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};

// Example
scrollToTop();

6.How to check if the parent element contains the child element?

const elementContains = (parent, child) => parent !== child && parent.contains(child);

// Examples
elementContains(document.querySelector('head'), document.querySelector('title'));
// true
elementContains(document.querySelector('body'), document.querySelector('body')); // false

7.How to check if the element specified is visible in the viewport?

const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
const { innerHeight, innerWidth } = window;
return partiallyVisible
? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};

// Examples
elementIsVisibleInViewport(el); // (not fully visible)
elementIsVisibleInViewport(el, true); // (partially visible)

8.How to fetch all images within an element?

const getImages = (el, includeDuplicates = false) => {
const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
return includeDuplicates ? images : [...new Set(images)];
};

// Examples
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']

9.How to figure out if the device is a mobile device or a desktop/laptop?

const detectDeviceType = () =>
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
? 'Mobile'
: 'Desktop';

// Example
detectDeviceType(); // "Mobile" or "Desktop"

10.How to get the current URL?

const currentURL = () => window.location.href;

// Example
currentURL(); // 'https://google.com'

11.How to create an object containing the parameters of the current URL?

const getURLParameters = url =>
(url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
(a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
{}
);

// Examples
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}

12.How to encode a set of form elements as an object?

const formToObject = form =>
Array.from(new FormData(form)).reduce(
(acc, [key, value]) => ({
...acc,
[key]: value
}),
{}
);

// Example
formToObject(document.querySelector('#form')); // { email: 'test@email.com', name: 'Test Name' }

13.How to retrieve a set of properties indicated by the given selectors from an object?

const get = (from, ...selectors) =>
[...selectors].map(s =>
s
.replace(/\[([^\[\]]*)\]/g, '.$1.')
.split('.')
.filter(t => t !== '')
.reduce((prev, cur) => prev && prev[cur], from)
);
const obj = { selector: { to: { val: 'val to select' } }, target: [1, 2, { a: 'test' }] };

// Example
get(obj, 'selector.to.val', 'target[0]', 'target[2].a'); // ['val to select', 1, 'test']

14.How to invoke the provided function after wait (in milliseconds)?

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
function(text) {
console.log(text);
},
1000,
'later'
);

// Logs 'later' after one second.

15.How to trigger a specific event on a given element, optionally passing custom data?

const triggerEvent = (el, eventType, detail) =>
el.dispatchEvent(new CustomEvent(eventType, { detail }));

// Examples
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });

16.How to remove an event listener from an element?

const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);

const fn = () => console.log('!');
document.body.addEventListener('click', fn);
off(document.body, 'click', fn); // no longer logs '!' upon clicking on the page

17.How to get readable format of the given number of milliseconds?

const formatDuration = ms => {
if (ms < 0) ms = -ms;
const time = {
day: Math.floor(ms / 86400000),
hour: Math.floor(ms / 3600000) % 24,
minute: Math.floor(ms / 60000) % 60,
second: Math.floor(ms / 1000) % 60,
millisecond: Math.floor(ms) % 1000
};
return Object.entries(time)
.filter(val => val[1] !== 0)
.map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
.join(', ');
};

// Examples
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); // '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

18.How to get the difference (in days) between two dates?

const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
(dateFinal - dateInitial) / (1000 * 3600 * 24);

// Example
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9

19.How to make a GET request to the passed URL?

const httpGet = (url, callback, err = console.error) => {
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.onload = () => callback(request.responseText);
request.onerror = () => err(request);
request.send();
};

httpGet(
'https://jsonplaceholder.typicode.com/posts/1',
console.log
);

// Logs: {"userId": 1, "id": 1, "title": "sample title", "body": "my text"}

20.How to make a POST request to the passed URL?

const httpPost = (url, data, callback, err = console.error) => {
const request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.onload = () => callback(request.responseText);
request.onerror = () => err(request);
request.send(data);
};

const newPost = {
userId: 1,
id: 1337,
title: 'Foo',
body: 'bar bar bar'
};
const data = JSON.stringify(newPost);
httpPost(
'https://jsonplaceholder.typicode.com/posts',
data,
console.log
);

// Logs: {"userId": 1, "id": 1337, "title": "Foo", "body": "bar bar bar"}

21.How to create a counter with the specified range, step and duration for the specified selector?

const counter = (selector, start, end, step = 1, duration = 2000) => {
let current = start,
_step = (end - start) * step < 0 ? -step : step,
timer = setInterval(() => {
current += _step;
document.querySelector(selector).innerHTML = current;
if (current >= end) document.querySelector(selector).innerHTML = end;
if (current >= end) clearInterval(timer);
}, Math.abs(Math.floor(duration / (end - start))));
return timer;
};

// Example
counter('#my-id', 1, 1000, 5, 2000); // Creates a 2-second timer for the element with id="my-id"

22.How to copy a string to the clipboard?

const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};

// Example
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.

23.How to find out if the browser tab of the page is focused?

const isBrowserTabFocused = () => !document.hidden;

// Example
isBrowserTabFocused(); // true

24.How to create a directory, if it does not exist?

const fs = require('fs');
const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);

// Example
createDirIfNotExists('test'); // creates the directory 'test', if it doesn't exist