{"@attributes":{"version":"2.0"},"channel":{"title":"DEV Community: Matvey Romanov","description":"The latest articles on DEV Community by Matvey Romanov (@ra1nbow1).","link":"https:\/\/dev.to\/ra1nbow1","image":{"url":"https:\/\/media2.dev.to\/dynamic\/image\/width=90,height=90,fit=cover,gravity=auto,format=auto\/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F431876%2F769a0b9f-63b1-401f-8342-7823141ff917.gif","title":"DEV Community: Matvey Romanov","link":"https:\/\/dev.to\/ra1nbow1"},"language":"en","item":[{"title":"Building Reliable Protected Routes with React Router v7","pubDate":"Sun, 08 Jun 2025 10:58:44 +0000","link":"https:\/\/dev.to\/ra1nbow1\/building-reliable-protected-routes-with-react-router-v7-1ka0","guid":"https:\/\/dev.to\/ra1nbow1\/building-reliable-protected-routes-with-react-router-v7-1ka0","description":"<h2>\n  \n  \n  Why You Need This\n<\/h2>\n\n<p>Imagine your site is a hip nightclub. The main doors are open to all, but there\u2019s a VIP area guarded by a bouncer: you need a secret pass (token) to get in. That bouncer on the front end is exactly what Protected Routes are for\u2014keeping un\u00adauthenticated users out of private pages.<\/p>\n\n<p>React Router v6 finally gave us the tools (like <code>&lt;Outlet \/&gt;<\/code>, <code>&lt;Navigate \/&gt;<\/code> and nested routes) to build this without hacky workarounds.<\/p>\n\n<h2>\n  \n  \n  Setting Up My AuthContext\n<\/h2>\n\n<p>First, I created an AuthContext with React\u2019s Context API to hold:<br>\n    \u2022 <code>isAuthenticated<\/code>: whether the user is logged in<br>\n    \u2022 <code>isLoading<\/code>: whether we\u2019re still checking their token<br>\n    \u2022 <code>userRole<\/code>: optional, for role-based guards<br>\n    \u2022 <code>login<\/code>\/<code>logout<\/code> functions<\/p>\n\n<p>This is like having a shared pizza fund: any component can peek in and see if there\u2019s enough dough (credentials) to grab a slice (access)!<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ AuthContext.tsx<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">React<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">createContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useEffect<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">react<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kr\">interface<\/span> <span class=\"nx\">AuthContextType<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nl\">isAuthenticated<\/span><span class=\"p\">:<\/span> <span class=\"nx\">boolean<\/span><span class=\"p\">;<\/span>\n  <span class=\"nl\">isLoading<\/span><span class=\"p\">:<\/span> <span class=\"nx\">boolean<\/span><span class=\"p\">;<\/span>\n  <span class=\"nl\">userRole<\/span><span class=\"p\">?:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">admin<\/span><span class=\"dl\">'<\/span> <span class=\"o\">|<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">user<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n  <span class=\"nl\">login<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"k\">void<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">;<\/span>\n  <span class=\"nl\">logout<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">void<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">AuthContext<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">createContext<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">AuthContextType<\/span> <span class=\"o\">|<\/span> <span class=\"kc\">undefined<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">(<\/span><span class=\"kc\">undefined<\/span><span class=\"p\">);<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">AuthProvider<\/span><span class=\"p\">:<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">FC<\/span><span class=\"o\">&lt;<\/span><span class=\"p\">{<\/span> <span class=\"na\">children<\/span><span class=\"p\">:<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">ReactNode<\/span> <span class=\"p\">}<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"p\">({<\/span> <span class=\"nx\">children<\/span> <span class=\"p\">})<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">isAuthenticated<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setIsAuthenticated<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">isLoading<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setIsLoading<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(<\/span><span class=\"kc\">true<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">userRole<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setUserRole<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"o\">&lt;<\/span><span class=\"dl\">'<\/span><span class=\"s1\">admin<\/span><span class=\"dl\">'<\/span> <span class=\"o\">|<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">user<\/span><span class=\"dl\">'<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">();<\/span>\n\n  <span class=\"nf\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ On mount, check token validity with server<\/span>\n    <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">checkAuth<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ pretend fetch to validate token<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">res<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nf\">fetch<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">\/api\/auth\/validate<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nf\">json<\/span><span class=\"p\">();<\/span>\n        <span class=\"nf\">setIsAuthenticated<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">ok<\/span><span class=\"p\">);<\/span>\n        <span class=\"nf\">setUserRole<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">role<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nf\">setIsAuthenticated<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span> <span class=\"k\">finally<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nf\">setIsLoading<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"nf\">checkAuth<\/span><span class=\"p\">();<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[]);<\/span>\n\n  <span class=\"kd\">const<\/span> <span class=\"nx\">login<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ call login API, then:<\/span>\n    <span class=\"nf\">setIsAuthenticated<\/span><span class=\"p\">(<\/span><span class=\"kc\">true<\/span><span class=\"p\">);<\/span>\n    <span class=\"nf\">setUserRole<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">user<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">};<\/span>\n\n  <span class=\"kd\">const<\/span> <span class=\"nx\">logout<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ clear token, etc.<\/span>\n    <span class=\"nf\">setIsAuthenticated<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\n    <span class=\"nf\">setUserRole<\/span><span class=\"p\">(<\/span><span class=\"kc\">undefined<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">};<\/span>\n\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">AuthContext<\/span><span class=\"p\">.<\/span><span class=\"nx\">Provider<\/span> <span class=\"nx\">value<\/span><span class=\"o\">=<\/span><span class=\"p\">{{<\/span> <span class=\"nx\">isAuthenticated<\/span><span class=\"p\">,<\/span> <span class=\"nx\">isLoading<\/span><span class=\"p\">,<\/span> <span class=\"nx\">userRole<\/span><span class=\"p\">,<\/span> <span class=\"nx\">login<\/span><span class=\"p\">,<\/span> <span class=\"nx\">logout<\/span> <span class=\"p\">}}<\/span><span class=\"o\">&gt;<\/span>\n      <span class=\"p\">{<\/span><span class=\"nx\">children<\/span><span class=\"p\">}<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"sr\">\/AuthContext.Provider<\/span><span class=\"err\">&gt;\n<\/span>  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"c1\">\/\/ Custom hook for easy access<\/span>\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">useAuth<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">ctx<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useContext<\/span><span class=\"p\">(<\/span><span class=\"nx\">AuthContext<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">ctx<\/span><span class=\"p\">)<\/span> <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">useAuth must be inside AuthProvider<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">ctx<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  My \u201cDigital Bouncer\u201d: the PrivateRoute Component\n<\/h2>\n\n<p>This component checks auth status, shows a loader while we wait, then either renders the protected content via <code>&lt;Outlet \/&gt;<\/code> or redirects to <code>\/login<\/code>, carrying along where we came from.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ PrivateRoute.tsx<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Navigate<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Outlet<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useLocation<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">react-router-dom<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useAuth<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/AuthContext<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">PrivateRoute<\/span><span class=\"p\">:<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">FC<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">isAuthenticated<\/span><span class=\"p\">,<\/span> <span class=\"nx\">isLoading<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useAuth<\/span><span class=\"p\">();<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">location<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useLocation<\/span><span class=\"p\">();<\/span>\n\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">isLoading<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Still verifying token\u2014show a spinner or message<\/span>\n    <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"nx\">Loading<\/span> <span class=\"nx\">authentication<\/span> <span class=\"nx\">status<\/span><span class=\"err\">\u2026<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/div&gt;<\/span><span class=\"err\">;\n<\/span>  <span class=\"p\">}<\/span>\n\n  <span class=\"c1\">\/\/ If logged in, render child routes; otherwise redirect to \/login<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">isAuthenticated<\/span> <span class=\"p\">?<\/span> <span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">Outlet<\/span> <span class=\"o\">\/&gt;<\/span>\n  <span class=\"p\">)<\/span> <span class=\"p\">:<\/span> <span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">Navigate<\/span>\n      <span class=\"nx\">to<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/login<\/span><span class=\"dl\">\"<\/span>\n      <span class=\"nx\">replace<\/span>\n      <span class=\"nx\">state<\/span><span class=\"o\">=<\/span><span class=\"p\">{{<\/span> <span class=\"na\">from<\/span><span class=\"p\">:<\/span> <span class=\"nx\">location<\/span> <span class=\"p\">}}<\/span> <span class=\"c1\">\/\/ remember original page<\/span>\n    <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Wrapping Routes with the Bouncer\n<\/h2>\n\n<p>In your main router file (e.g. <code>App.tsx<\/code>), group all private pages under one <code>&lt;Route element={&lt;PrivateRoute \/&gt;}&gt;<\/code>. It\u2019s like fencing off the VIP area in one go:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ App.tsx<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">BrowserRouter<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Routes<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Route<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">react-router-dom<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AuthProvider<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/AuthContext<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">PrivateRoute<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/PrivateRoute<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">Home<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/Home<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">Login<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/Login<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">Dashboard<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/Dashboard<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">Profile<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/Profile<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nf\">App<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">AuthProvider<\/span><span class=\"o\">&gt;<\/span>\n      <span class=\"o\">&lt;<\/span><span class=\"nx\">BrowserRouter<\/span><span class=\"o\">&gt;<\/span>\n        <span class=\"o\">&lt;<\/span><span class=\"nx\">Routes<\/span><span class=\"o\">&gt;<\/span>\n          <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Home<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>\n          <span class=\"p\">{<\/span><span class=\"cm\">\/* Protected \u201cVIP\u201d routes *\/<\/span><span class=\"p\">}<\/span>\n          <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">PrivateRoute<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span><span class=\"o\">&gt;<\/span>\n            <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/dashboard<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Dashboard<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>            <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/profile<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Profile<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>          <span class=\"o\">&lt;<\/span><span class=\"sr\">\/Route<\/span><span class=\"err\">&gt;\n<\/span>\n          <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/login<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Login<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>        <span class=\"o\">&lt;<\/span><span class=\"sr\">\/Routes<\/span><span class=\"err\">&gt;\n<\/span>      <span class=\"o\">&lt;<\/span><span class=\"sr\">\/BrowserRouter<\/span><span class=\"err\">&gt;\n<\/span>    <span class=\"o\">&lt;<\/span><span class=\"sr\">\/AuthProvider<\/span><span class=\"err\">&gt;\n<\/span>  <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"nx\">App<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Speeding Things Up with Lazy Loading\n<\/h2>\n\n<p>To keep our main bundle slim, I wrapped my private pages in React.lazy and , so they load only when someone actually goes looking for them\u2014like serving dishes only when ordered:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ LazyRoutes.tsx<\/span>\n<span class=\"k\">import<\/span> <span class=\"nx\">React<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Suspense<\/span><span class=\"p\">,<\/span> <span class=\"nx\">lazy<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">react<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Routes<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Route<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">react-router-dom<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">PrivateRoute<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">.\/PrivateRoute<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">Dashboard<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">lazy<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">import<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">.\/Dashboard<\/span><span class=\"dl\">'<\/span><span class=\"p\">));<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">Profile<\/span>   <span class=\"o\">=<\/span> <span class=\"nf\">lazy<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">import<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">.\/Profile<\/span><span class=\"dl\">'<\/span><span class=\"p\">));<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">Login<\/span>     <span class=\"o\">=<\/span> <span class=\"nf\">lazy<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">import<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">.\/Login<\/span><span class=\"dl\">'<\/span><span class=\"p\">));<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">LazyRoutes<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">Suspense<\/span> <span class=\"nx\">fallback<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"nx\">Loading<\/span> <span class=\"kr\">module<\/span><span class=\"err\">\u2026<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/div&gt;}<\/span><span class=\"err\">&gt;\n<\/span>      <span class=\"o\">&lt;<\/span><span class=\"nx\">Routes<\/span><span class=\"o\">&gt;<\/span>\n        <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/login<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Login<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>\n        <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">PrivateRoute<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span><span class=\"o\">&gt;<\/span>\n          <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/dashboard<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Dashboard<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>          <span class=\"o\">&lt;<\/span><span class=\"nx\">Route<\/span> <span class=\"nx\">path<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/profile<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">element<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Profile<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\n<\/span>        <span class=\"o\">&lt;<\/span><span class=\"sr\">\/Route<\/span><span class=\"err\">&gt;\n<\/span>      <span class=\"o\">&lt;<\/span><span class=\"sr\">\/Routes<\/span><span class=\"err\">&gt;\n<\/span>    <span class=\"o\">&lt;<\/span><span class=\"sr\">\/Suspense<\/span><span class=\"err\">&gt;\n<\/span>  <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Bonus: Role-Based Gates and Memory\n<\/h2>\n\n<p>If you need role checks, add an <code>allowedRoles<\/code> prop to <code>PrivateRoute<\/code>:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ Extended PrivateRoute with roles<\/span>\n<span class=\"kr\">interface<\/span> <span class=\"nx\">PrivateRouteProps<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nl\">allowedRoles<\/span><span class=\"p\">?:<\/span> <span class=\"nb\">Array<\/span><span class=\"o\">&lt;<\/span><span class=\"dl\">'<\/span><span class=\"s1\">admin<\/span><span class=\"dl\">'<\/span> <span class=\"o\">|<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">user<\/span><span class=\"dl\">'<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">PrivateRoute<\/span><span class=\"p\">:<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">FC<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">PrivateRouteProps<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"p\">({<\/span> <span class=\"nx\">allowedRoles<\/span> <span class=\"p\">})<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">isAuthenticated<\/span><span class=\"p\">,<\/span> <span class=\"nx\">isLoading<\/span><span class=\"p\">,<\/span> <span class=\"nx\">userRole<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useAuth<\/span><span class=\"p\">();<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">location<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useLocation<\/span><span class=\"p\">();<\/span>\n\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">isLoading<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"nx\">Loading<\/span><span class=\"err\">\u2026<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/div&gt;<\/span><span class=\"err\">;\n<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">isAuthenticated<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">Navigate<\/span> <span class=\"nx\">to<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/login<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">replace<\/span> <span class=\"nx\">state<\/span><span class=\"o\">=<\/span><span class=\"p\">{{<\/span> <span class=\"na\">from<\/span><span class=\"p\">:<\/span> <span class=\"nx\">location<\/span> <span class=\"p\">}}<\/span> <span class=\"sr\">\/&gt;<\/span><span class=\"err\">;\n<\/span>  <span class=\"p\">}<\/span>\n\n  <span class=\"c1\">\/\/ If roles are provided, check them<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">allowedRoles<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"o\">!<\/span><span class=\"nx\">allowedRoles<\/span><span class=\"p\">.<\/span><span class=\"nf\">includes<\/span><span class=\"p\">(<\/span><span class=\"nx\">userRole<\/span><span class=\"o\">!<\/span><span class=\"p\">))<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Could show a \u201c403 Forbidden\u201d page instead<\/span>\n    <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">Navigate<\/span> <span class=\"nx\">to<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\/unauthorized<\/span><span class=\"dl\">\"<\/span> <span class=\"nx\">replace<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">Outlet<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>And thanks to <code>state.from<\/code> in <code>&lt;Navigate \/&gt;<\/code>, after a successful login you can send the user right back where they came from\u2014like bookmarking their spot in the club.<\/p>\n\n<p>What I Took Away from This<br>\n    \u2022 <strong>Centralized &amp; DRY<\/strong>: One context + one route guard\u2014no copy-paste checks.<br>\n    \u2022 <strong>Clear analogies<\/strong>: Bouncer, VIP, pizza fund\u2014keeps concepts memorable.<br>\n    \u2022 <strong>Performance<\/strong>: Lazy loading private modules keeps initial load quick.<br>\n    \u2022 <strong>Flexibility<\/strong>: Easy to layer in roles, custom redirects, and more.<\/p>\n\n<p>Give your feedback and follow my <a href=\"https:\/\/github.com\/ra1nbow1\" rel=\"noopener noreferrer\">Github<\/a><\/p>\n\n","category":["webdev","programming","typescript","react"]},{"title":"Supercharging React Performance: Best Tips and Tools","pubDate":"Thu, 01 Feb 2024 21:24:55 +0000","link":"https:\/\/dev.to\/ra1nbow1\/supercharging-react-performance-best-tips-and-tools-4ff0","guid":"https:\/\/dev.to\/ra1nbow1\/supercharging-react-performance-best-tips-and-tools-4ff0","description":"<p>When it comes to building lightning-fast web applications with React, optimizing performance is the name of the game. In this guide, we'll dive deep into the world of React performance optimization, uncovering the best practices and tools to turbocharge your React apps.<\/p>\n\n<h2>\n  \n  \n  The Need for Speed\n<\/h2>\n\n<p>In today's fast-paced digital world, users expect websites and web apps to load quickly and respond instantaneously to their interactions. Slow-loading or sluggish apps can lead to frustrated users and high bounce rates. That's where React performance optimization comes into play. By fine-tuning your React apps for speed and efficiency, you can deliver a seamless and delightful user experience that keeps users coming back for more.<\/p>\n\n<h2>\n  \n  \n  Best Practices for Lightning-Fast React Apps\n<\/h2>\n\n<h3>\n  \n  \n  1. Optimize Component Rendering\n<\/h3>\n\n<h4>\n  \n  \n  Leverage PureComponent and React.memo\n<\/h4>\n\n<p>Using PureComponent and React.memo can prevent unnecessary re-renders by performing efficient shallow comparisons of props and state. This can significantly improve performance, especially for components with complex rendering logic.<\/p>\n\n<h4>\n  \n  \n  Minimize Inline Functions\n<\/h4>\n\n<p>Avoid creating new function instances inside render methods, as this can lead to unnecessary re-renders. Instead, use useCallback and useMemo hooks to memoize functions and values, reducing the risk of performance bottlenecks.<\/p>\n\n<h3>\n  \n  \n  2. Harness the Power of Lifecycle Methods\n<\/h3>\n\n<h4>\n  \n  \n  Use componentDidMount and componentDidUpdate Wisely\n<\/h4>\n\n<p>Perform expensive operations such as data fetching or subscriptions in componentDidMount and componentDidUpdate lifecycle methods. By deferring these operations until after the initial render, you can ensure a smoother user experience.<\/p>\n\n<h4>\n  \n  \n  Implement shouldComponentUpdate\n<\/h4>\n\n<p>Override shouldComponentUpdate to control when a component should re-render based on changes in props and state. This can help minimize unnecessary re-renders and optimize performance.<\/p>\n\n<h3>\n  \n  \n  3. Fine-Tune List Rendering\n<\/h3>\n\n<h4>\n  \n  \n  Provide Unique Keys\n<\/h4>\n\n<p>When rendering lists, always provide unique keys to help React identify which items have changed, added, or removed. This can prevent unnecessary re-renders and improve overall performance.<\/p>\n\n<h4>\n  \n  \n  Batch Updates\n<\/h4>\n\n<p>Utilize React's batched updates mechanism to minimize the number of re-renders when updating lists. By batching multiple updates into a single render pass, you can optimize performance and ensure a smoother user experience.<\/p>\n\n<h3>\n  \n  \n  4. Embrace Code Splitting and Lazy Loading\n<\/h3>\n\n<h4>\n  \n  \n  Break Down Large Bundles\n<\/h4>\n\n<p>Split large bundles into smaller chunks using code splitting techniques. This can reduce initial load times and improve overall performance, especially for larger applications with complex codebases.<\/p>\n\n<h4>\n  \n  \n  Lazy Load Components\n<\/h4>\n\n<p>Use React.lazy and Suspense to lazily load components that are not immediately needed. This can help reduce the initial bundle size and improve load times, particularly for apps with multiple routes or complex UIs.<\/p>\n\n<h3>\n  \n  \n  5. Harness the Power of Memoization and Caching\n<\/h3>\n\n<h4>\n  \n  \n  Memoize Expensive Computations\n<\/h4>\n\n<p>Memoize expensive computations using libraries like memoize-one to avoid redundant calculations. By caching the results of expensive operations, you can improve performance and optimize resource utilization.<\/p>\n\n<h4>\n  \n  \n  Cache Data\n<\/h4>\n\n<p>Cache data fetched from APIs or expensive computations to prevent unnecessary re-fetching or re-computation. By storing data in memory or leveraging browser caching mechanisms, you can reduce network latency and improve app responsiveness.<\/p>\n\n<h2>\n  \n  \n  Tools of the Trade: Performance Optimization Tools for React\n<\/h2>\n\n<h3>\n  \n  \n  1. React DevTools\n<\/h3>\n\n<p>React DevTools provides a suite of tools for debugging and profiling React applications. From inspecting component hierarchies to analyzing performance bottlenecks, React DevTools is an indispensable tool for React developers.<\/p>\n\n<h3>\n  \n  \n  2. Webpack Bundle Analyzer\n<\/h3>\n\n<p>Webpack Bundle Analyzer helps analyze the size of webpack bundles and identify opportunities for optimization. By visualizing the composition of your bundles, you can pinpoint large dependencies or chunks that can be split or optimized.<\/p>\n\n<h3>\n  \n  \n  3. Performance Monitoring Tools\n<\/h3>\n\n<p>Tools like Lighthouse, Google PageSpeed Insights, and Web Vitals provide insights into various performance metrics such as load times, time to interactive, and cumulative layout shift. By monitoring these metrics, you can identify areas for improvement and ensure optimal performance across different devices and network conditions.<\/p>\n\n<h3>\n  \n  \n  4. Code Quality Tools\n<\/h3>\n\n<p>ESLint and other code quality tools can help identify potential performance issues, such as inefficient code patterns or unnecessary re-renders. By enforcing best practices and performance optimizations, you can maintain high code quality and ensure optimal app performance.<\/p>\n\n<h3>\n  \n  \n  5. React Profiler\n<\/h3>\n\n<p>React Profiler is a built-in tool for profiling React components and identifying performance issues. By visualizing component render times, update times, and reconciliations, React Profiler provides valuable insights into component performance and helps optimize app performance.<\/p>\n\n<h2>\n  \n  \n  Speed Up Your React Apps Today!\n<\/h2>\n\n<p>Optimizing performance in React is essential for delivering fast, responsive, and engaging user experiences. By following best practices such as minimizing render operations, optimizing component lifecycle methods, and leveraging tools like React DevTools and Webpack Bundle Analyzer, you can identify and address performance bottlenecks in your applications. With the right tools and techniques, you can ensure that your React apps provide a smooth and enjoyable user experience across various devices and network conditions.<\/p>\n\n<p>So why wait? Start optimizing your React apps today and supercharge your performance like never before!<\/p>\n\n","category":["webdev","javascript","react","performance"]},{"title":"Microservice architecture - Benefits, how to implement, challenges, etc.","pubDate":"Sun, 23 Jul 2023 19:15:27 +0000","link":"https:\/\/dev.to\/ra1nbow1\/microservice-architecture-benefits-how-to-implement-challenges-etc-4e8l","guid":"https:\/\/dev.to\/ra1nbow1\/microservice-architecture-benefits-how-to-implement-challenges-etc-4e8l","description":"<h2>\n  \n  \n  Microservice Architecture\n<\/h2>\n\n<p>Microservice architecture is an architectural style that structures an application as a collection of loosely coupled services. Each service runs in its own processes and communicates through APIs. Microservices aim to overcome the limitations of monolithic architecture.<\/p>\n\n<h2>\n  \n  \n  Benefits of Microservice Architecture\n<\/h2>\n\n<ul>\n<li>\n<strong>Scalability:<\/strong> Since each service is independent, they can be scaled horizontally by adding more instances of that service. This makes it easy to scale individual components based on demand.\n<\/li>\n<li>\n<strong>Agility:<\/strong> Services are developed, deployed and scaled independently. Developers can quickly update or replace a service without affecting others. This results in rapid, independent development and release cycles.<\/li>\n<li>\n<strong>Fault isolation:<\/strong> Since each service has its own processes and resources, a failure in one service does not affect other services. This improves fault tolerance and reliability. The entire system does not have to be restarted for a single service failure.<\/li>\n<li>\n<strong>Polyglot persistence:<\/strong> Services are not restricted to any specific data store. They can use different databases and storage technologies based on their needs. This improves flexibility.<\/li>\n<li>\n<strong>Independence of teams:<\/strong> Since each service is independent, different teams can work on different services concurrently. This allows for separation of concerns and specialized teams.<\/li>\n<\/ul>\n\n<h2>\n  \n  \n  How to Implement Microservices\n<\/h2>\n\n<ul>\n<li>\n<strong>Define domain-driven services:<\/strong> Identify core business capabilities and create independent services around those domains. This results in high cohesion within services and loose coupling between services.<\/li>\n<li>\n<strong>Use lightweight protocols:<\/strong> Services should communicate using lightweight protocols like HTTP\/RESTful APIs and message queues. This decouples services and makes them independently deployable.<\/li>\n<li>\n<strong>Deploy independently:<\/strong> Services should be packaged independently so they can be deployed, upgraded and scaled independently. They should be able to run on any environment or platform.<\/li>\n<li>\n<strong>Replicate non-functional requirements:<\/strong> Each service should be self-sufficient by replicating non-functional requirements like security, logging, monitoring, caching, etc.<\/li>\n<li>\n<strong>Use service discovery:<\/strong> A service discovery mechanism is required to dynamically find and register microservices. This allows services to locate each other at runtime.\n<\/li>\n<li>\n<strong>Plan for failure:<\/strong> Failures are inevitable in distributed systems. Plan for failure scenarios and implement retries, timeouts, circuit breakers, and fallback mechanisms.<\/li>\n<\/ul>\n\n<h2>\n  \n  \n  Challenges of Microservice Architecture\n<\/h2>\n\n<ul>\n<li>\n<strong>Increased complexity:<\/strong> Due to the distributed nature, microservices introduce operational complexity. Managing many independent services requires orchestration, discovery, monitoring, logging, etc.<\/li>\n<li>\n<strong>Orchestration challenges:<\/strong> Coordinating and choreographing interactions between independent services can be challenging. Service mesh architectures are emerging to simplify service orchestration.\n<\/li>\n<li>\n<strong>Testing issues:<\/strong> Testing interactions between independently deployed services is hard. Test strategies like contract testing, chaos testing, etc. are required.<\/li>\n<li>\n<strong>Debugging difficulties:<\/strong> Distributed tracing and logs correlation techniques are required to effectively debug microservices.<\/li>\n<\/ul>\n\n<p>While microservice architecture brings many benefits, it also introduces operational challenges due to its distributed nature. A well-planned microservices implementation that addresses these challenges can provide an effective architecture for building scalable, modular applications.<\/p>\n\n","category":["programming","webdev","architecture"]},{"title":"How to write the right API client in TypeScript","pubDate":"Sat, 17 Jun 2023 20:31:39 +0000","link":"https:\/\/dev.to\/ra1nbow1\/how-to-write-the-right-api-client-in-typescript-38g3","guid":"https:\/\/dev.to\/ra1nbow1\/how-to-write-the-right-api-client-in-typescript-38g3","description":"<p>In this article, I will talk in detail about the implementation of the client API in TypeScript for working with both third-party APIs and my own. The client can work with public and protected endpoints and is not tied to a specific framework, which makes it suitable for use in React, Vue, Svelte and other frameworks.<\/p>\n\n<p>Creating an application is more complicated than a ToDo list, most often we need to interact with some data stored on the server. These can be weather forecasts processed by a third-party API, as well as our customers' data, be it their login and password or a shopping list in the store. Working with a SPA (Single Page Application) application, we need to receive, modify and send this very data from the client side. Therefore, you need to have some kind of layer responsible for interacting with the server. In this article, we will consider using the API client with the React library, although it can be safely used on the same Vue, Svelte, and so on.<\/p>\n\n<h2>\n  \n  \n  Why not register all queries in the components where they are used?\n<\/h2>\n\n<p>It's simple: if you change the API interface you are working with, you will have to go through all the code and find all the points of change that it affected. You can try to put this logic into React hooks, since we are talking about it now, but this solution will not be able to be used in other projects with other frameworks.<\/p>\n\n<h2>\n  \n  \n  TypeScript implementation\n<\/h2>\n\n<p>To begin with, we will put the domains where the API is located in a kind of config that works with the <code>.env<\/code> file:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">REACT_APP_API_BASE_URL<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">http:\/\/localhost:8083<\/span><span class=\"dl\">\"<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">get<\/span> <span class=\"nf\">apiBaseUrl<\/span><span class=\"p\">():<\/span> <span class=\"nx\">string<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">env<\/span><span class=\"p\">.<\/span><span class=\"nx\">REACT_APP_API_BASE_URL<\/span> <span class=\"o\">||<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">},<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Then we will write an abstract client itself, not tied to this domain. It will require the <strong>axios<\/strong> and <strong>axios-extensions<\/strong> libraries to work.<\/p>\n\n<p><strong>Client Code:<\/strong><br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">import<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">AxiosInstance<\/span><span class=\"p\">,<\/span> <span class=\"nx\">AxiosRequestConfig<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">axios<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">Forbidden<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">HttpError<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">Unauthorized<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">..\/errors<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Headers<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/types<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">ApiClient<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">constructor<\/span><span class=\"p\">(<\/span>\n        <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">baseUrl<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span><span class=\"p\">,<\/span>\n        <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">headers<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Headers<\/span><span class=\"p\">,<\/span>\n        <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">authToken<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"\"<\/span>\n    <span class=\"p\">)<\/span> <span class=\"p\">{}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"k\">async<\/span> <span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">params<\/span><span class=\"p\">?:<\/span> <span class=\"nx\">any<\/span><span class=\"p\">,<\/span> <span class=\"nx\">signal<\/span><span class=\"p\">?:<\/span> <span class=\"nx\">AbortSignal<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">any<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">client<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">createClient<\/span><span class=\"p\">(<\/span><span class=\"nx\">params<\/span><span class=\"p\">);<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">response<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">client<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">signal<\/span> <span class=\"p\">});<\/span>\n            <span class=\"k\">return<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"na\">error<\/span><span class=\"p\">:<\/span> <span class=\"nx\">any<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">handleError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"k\">async<\/span> <span class=\"nf\">post<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">data<\/span><span class=\"p\">?:<\/span> <span class=\"nx\">any<\/span><span class=\"p\">,<\/span> <span class=\"nx\">signal<\/span><span class=\"p\">?:<\/span> <span class=\"nx\">AbortSignal<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">any<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">client<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">createClient<\/span><span class=\"p\">();<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">response<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">client<\/span><span class=\"p\">.<\/span><span class=\"nf\">post<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">,<\/span> <span class=\"nx\">data<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">signal<\/span> <span class=\"p\">});<\/span>\n            <span class=\"k\">return<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">handleError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"k\">async<\/span> <span class=\"nf\">uploadFile<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">formData<\/span><span class=\"p\">:<\/span> <span class=\"nx\">FormData<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">any<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">client<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">createClient<\/span><span class=\"p\">();<\/span>\n            <span class=\"kd\">const<\/span> <span class=\"nx\">response<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">client<\/span><span class=\"p\">.<\/span><span class=\"nf\">post<\/span><span class=\"p\">(<\/span><span class=\"nx\">endpoint<\/span><span class=\"p\">,<\/span> <span class=\"nx\">formData<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n                <span class=\"na\">headers<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n                    <span class=\"dl\">\"<\/span><span class=\"s2\">Content-Type<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">multipart\/form-data<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n                <span class=\"p\">}<\/span>\n            <span class=\"p\">})<\/span>\n            <span class=\"k\">return<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">handleError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">private<\/span> <span class=\"nf\">createClient<\/span><span class=\"p\">(<\/span><span class=\"nx\">params<\/span><span class=\"p\">:<\/span> <span class=\"nx\">object<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}):<\/span> <span class=\"nx\">AxiosInstance<\/span> <span class=\"p\">{<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">config<\/span><span class=\"p\">:<\/span> <span class=\"nx\">AxiosRequestConfig<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n            <span class=\"na\">baseURL<\/span><span class=\"p\">:<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">baseUrl<\/span><span class=\"p\">,<\/span>\n            <span class=\"na\">headers<\/span><span class=\"p\">:<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">,<\/span>\n            <span class=\"na\">params<\/span><span class=\"p\">:<\/span> <span class=\"nx\">params<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">authToken<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"nx\">config<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n                <span class=\"na\">Authorization<\/span><span class=\"p\">:<\/span> <span class=\"s2\">`Bearer <\/span><span class=\"p\">${<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">authToken<\/span><span class=\"p\">}<\/span><span class=\"s2\">`<\/span><span class=\"p\">,<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">.<\/span><span class=\"nf\">create<\/span><span class=\"p\">(<\/span><span class=\"nx\">config<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">private<\/span> <span class=\"nf\">handleError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">:<\/span> <span class=\"nx\">any<\/span><span class=\"p\">):<\/span> <span class=\"nx\">never<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">response<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">HttpError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">message<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">status<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">401<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Unauthorized<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">status<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">403<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Forbidden<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">throw<\/span> <span class=\"nx\">error<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The client uses custom types such as <code>Headers<\/code>, which, in fact, is just a dictionary <strong>[key: string]: string<\/strong>, and various errors that inherit the global <code>Error<\/code> class (Unauthorized, Forbidden, HTTPError), so that in the future it will be easier to understand what caused them.<\/p>\n\n<p>The class has only three public methods, which generate an axios client every time they are used. This client can work with both public API endpoints and protected ones by adding a header with a Bearer token. How the client receives this very token will be discussed later. Both the get and post methods use the optional <code>abort Signal<\/code> parameter, which allows you to interrupt the sending of the request depending on the user's actions.<\/p>\n\n<p>In the case of sending any files to the server, the client uses the <code>uploadFile()<\/code> method, sending a request to the server with the <strong>Content-Type: multipart\/form-data<\/strong> header.<\/p>\n\n<p>To encapsulate the logic of creating these clients, we will write a factory.<\/p>\n\n<p><strong>Factory Code:<\/strong><br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Headers<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/..\/types<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">ApiClient<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/..\/clients<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">ApiClientFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">constructor<\/span><span class=\"p\">(<\/span>\n        <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">baseUrl<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span><span class=\"p\">,<\/span>\n        <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">headers<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Headers<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n    <span class=\"p\">)<\/span> <span class=\"p\">{}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"nf\">createClient<\/span><span class=\"p\">():<\/span> <span class=\"nx\">ApiClient<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ApiClient<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">baseUrl<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"nf\">createAuthorizedClient<\/span><span class=\"p\">(<\/span><span class=\"nx\">authToken<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span><span class=\"p\">):<\/span> <span class=\"nx\">ApiClient<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ApiClient<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">baseUrl<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">,<\/span> <span class=\"nx\">authToken<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>It doesn't do anything complicated: it just creates either a regular client or an authorized one, passing a token to the constructor.<\/p>\n\n<h2>\n  \n  \n  Specific implementation\n<\/h2>\n\n<p>Now we need to adapt this abstract client to some specific endpoint. For example, let's create a manager that receives the latest status of the user profile from the server:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">ApiClientInterface<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/clients<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Profile<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/models<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">ProfileManager<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">constructor<\/span><span class=\"p\">(<\/span><span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">apiClient<\/span><span class=\"p\">:<\/span> <span class=\"nx\">ApiClientInterface<\/span><span class=\"p\">)<\/span> <span class=\"p\">{}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"k\">async<\/span> <span class=\"nf\">get<\/span><span class=\"p\">():<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Profile<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">apiClient<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"\"<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>In this example, we don't care about the model we use for the profile. Let's just assume that it is compatible with the value transmitted from the server.<\/p>\n\n<p>The manager class itself uses composition and stores the client object in its state in order to forward all API requests to it, and if necessary, it can add some logic of its own to the received value (perform validation, create its own endpoint, and so on).<\/p>\n\n<p>Most often, APIs group domain logic by adding a specific prefix to their endpoints. There are also cases of API migration from one version to a newer one. To provide for all this, we will create a factory for this particular manager.<\/p>\n\n<p><strong>Factory Code:<\/strong><br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">ApiClientFactory<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/clients<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Headers<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/types<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">ProfileManager<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/ProfileManager<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nc\">ProfileManagerFactory<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">private<\/span> <span class=\"nx\">readonly<\/span> <span class=\"nx\">apiClientFactory<\/span><span class=\"p\">:<\/span> <span class=\"nx\">ApiClientFactory<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"nf\">constructor<\/span><span class=\"p\">(<\/span><span class=\"nx\">baseUrl<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span><span class=\"p\">,<\/span> <span class=\"nx\">headers<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Headers<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">apiClientFactory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ApiClientFactory<\/span><span class=\"p\">(<\/span>\n            <span class=\"s2\">`<\/span><span class=\"p\">${<\/span><span class=\"nx\">baseUrl<\/span><span class=\"p\">}<\/span><span class=\"s2\">\/api\/v1\/profile`<\/span><span class=\"p\">,<\/span>\n            <span class=\"nx\">headers<\/span>\n        <span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">public<\/span> <span class=\"nf\">createProfileManager<\/span><span class=\"p\">(<\/span><span class=\"nx\">authToken<\/span><span class=\"p\">:<\/span> <span class=\"nx\">string<\/span><span class=\"p\">):<\/span> <span class=\"nx\">ProfileManager<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">ProfileManager<\/span><span class=\"p\">(<\/span>\n            <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">apiClientFactory<\/span><span class=\"p\">.<\/span><span class=\"nf\">createAuthorizedClient<\/span><span class=\"p\">(<\/span><span class=\"nx\">authToken<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>When creating this factory, the domain URL and headers for the request are passed to the constructor. Then these parameters are passed to the client API factory constructor, adding the API version and the same prefix denoting part of the domain logic after the passed URL. When creating a user profile manager, authorization is required, so a token is passed to the method, on the basis of which a client with an authorization header is created.<\/p>\n\n<h2>\n  \n  \n  Dependency injection\n<\/h2>\n\n<p>Now all that remains is to write a function that will be responsible for providing a working profile manager in any part of the code, be it a React component or an independent TypeScript class. It will look something like this:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">createProfileManager<\/span><span class=\"p\">():<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">apiClient<\/span><span class=\"p\">.<\/span><span class=\"nx\">ProfileManager<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">factory<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">apiClient<\/span><span class=\"p\">.<\/span><span class=\"nc\">ProfileManagerFactory<\/span><span class=\"p\">(<\/span><span class=\"nx\">apiClientConfig<\/span><span class=\"p\">.<\/span><span class=\"nx\">apiBaseUrl<\/span><span class=\"p\">,<\/span> <span class=\"nf\">getBaseHeaders<\/span><span class=\"p\">());<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">factory<\/span><span class=\"p\">.<\/span><span class=\"nf\">createProfileManager<\/span><span class=\"p\">(<\/span><span class=\"k\">await<\/span> <span class=\"nf\">getAuthToken<\/span><span class=\"p\">());<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>First, a factory of these managers is created inside, to which the server domain and the base headers are transferred, which look like this:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">getBaseHeaders<\/span><span class=\"p\">():<\/span> <span class=\"nx\">apiClient<\/span><span class=\"p\">.<\/span><span class=\"nx\">Headers<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"p\">{<\/span>\n        <span class=\"dl\">\"<\/span><span class=\"s2\">Accept-Language<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">en<\/span><span class=\"dl\">\"<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>If desired, you can add any of your own headers at the level of the manager creation function.<\/p>\n\n<p>I will not discuss the method of obtaining an API token and the operation of the <code>getAuthToken()<\/code> function in this article, because this topic deserves a separate publication.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">getAuthToken<\/span><span class=\"p\">():<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">string<\/span><span class=\"o\">&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ \u0417There would be a token receipt code here, but for now...<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">localStorage<\/span><span class=\"p\">.<\/span><span class=\"nf\">getItem<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">auth-token<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Use in components\n<\/h2>\n\n<p>An example of the profile manager is presented below:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nf\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"p\">(<\/span><span class=\"k\">async <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n                <span class=\"k\">await<\/span> <span class=\"nf\">initProfile<\/span><span class=\"p\">();<\/span>\n            <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"na\">error<\/span><span class=\"p\">:<\/span> <span class=\"nx\">any<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n                <span class=\"k\">await<\/span> <span class=\"nf\">handleError<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">);<\/span>\n            <span class=\"p\">}<\/span> <span class=\"k\">finally<\/span> <span class=\"p\">{<\/span>\n                <span class=\"nf\">setLoading<\/span><span class=\"p\">(<\/span><span class=\"kc\">false<\/span><span class=\"p\">);<\/span>\n            <span class=\"p\">}<\/span>\n        <span class=\"p\">})()<\/span>\n    <span class=\"p\">},<\/span> <span class=\"p\">[]);<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"nx\">initProfile<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">manager<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nf\">createProfileManager<\/span><span class=\"p\">();<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">profile<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">manager<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">();<\/span>\n        <span class=\"k\">await<\/span> <span class=\"nf\">dispatch<\/span><span class=\"p\">(<\/span><span class=\"nf\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">profile<\/span><span class=\"p\">));<\/span>\n    <span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>When the function is run in the <code>useEffect<\/code> hook, a profile manager is asynchronously created, which then requests the current status of the user profile from the server. In this example, we simply write the received state to the Redux storage, so that we can then work with this profile without re-requesting it from the server each time. In case of a client error, the <code>handleError()<\/code> function is launched, which, depending on the type of error, as I mentioned earlier, performs certain actions.<\/p>\n\n<h2>\n  \n  \n  Results\n<\/h2>\n\n<p>This implementation is independent of the framework you are working with, it can be used even on native JS (TS). There are a lot of things you can refine in it, for example, add a \"Builder\" pattern to create an API client and transfer parameters, abortsignals and other things to it, or make a variable authentication system via a JWT token. Everything is at your discretion). In the next article I will tell you about the method of obtaining and working with API tokens on the client.<\/p>\n\n<p>Follow me on <a href=\"https:\/\/github.com\/ra1nbow1\">Github<\/a> &lt;3<\/p>\n\n","category":["programming","typescript","webdev","backend"]},{"title":"Useful Built-In JavaScript Web APIs","pubDate":"Sun, 23 Apr 2023 20:10:58 +0000","link":"https:\/\/dev.to\/ra1nbow1\/useful-built-in-javascript-web-apis-4oi7","guid":"https:\/\/dev.to\/ra1nbow1\/useful-built-in-javascript-web-apis-4oi7","description":"<p>An Application Programming Interface (API) is a software interface that allows two or more programs to communicate by acting as an intermediary between them.<\/p>\n\n<p>All browsers have a set of built-in APIs that extend their functionality, usually by supporting complex operations.<\/p>\n\n<p>In this article, you will learn about four built-in JavaScript Web APIs you can use in your projects.<\/p>\n\n<h1>\n  \n  \n  The Notification API\n<\/h1>\n\n<p>The notification API is a built-in browser API that allows web pages to display notifications to the end user. The notifications generated with this API can be displayed even if the user has switched tabs or is on a different app, provided the user has granted the required permissions.<\/p>\n\n<h2>\n  \n  \n  Requesting Permission\n<\/h2>\n\n<p>Before a notification can be displayed on a user\u2019s window, the user must first grant notification permissions to the application.<\/p>\n\n<p>It is regarded as good practice to ask for user permission in response to a user gesture, for example, clicking a button. Many browsers have already disallowed permission requests not triggered by a user gesture due to the abuse of push notifications in the past.<\/p>\n\n<p>You can request notification permissions for your application by calling the <code>requestPermission<\/code> method on the <code>Notification<\/code> class in response to a user gesture. The <code>requestPermision<\/code> method is available in a promise-based version and a callback version (supported in older browsers).<\/p>\n\n<p>For example<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">noficationButton<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nf\">getElementById<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">notify<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">requestPermission<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">function <\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/check if the browser supports notifications<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Notification<\/span><span class=\"dl\">\"<\/span> <span class=\"k\">in<\/span> <span class=\"nb\">window<\/span><span class=\"p\">))<\/span>\n    <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Browser does not support notifications<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n\n  <span class=\"c1\">\/\/Request permission (Promise-based)<\/span>\n  <span class=\"nx\">Notification<\/span><span class=\"p\">.<\/span><span class=\"nf\">requestPermission<\/span><span class=\"p\">().<\/span><span class=\"nf\">then<\/span><span class=\"p\">((<\/span><span class=\"nx\">status<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">status<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">});<\/span>\n<span class=\"p\">};<\/span>\n<span class=\"c1\">\/\/Ask for permission in response to a gesture<\/span>\n<span class=\"nx\">noficationButton<\/span><span class=\"p\">.<\/span><span class=\"nf\">addEventListener<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">click<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">requestPermission<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>In the <code>requestPermission<\/code> function above, you first check if the user\u2019s browser supports notifications by checking for the 1Notification1 object in the <code>window<\/code> object.<\/p>\n\n<p>Next, you call <code>requestPermission<\/code> method on the <code>Notification<\/code> class. This method returns a promise that, when resolved, returns <code>granted<\/code> or <code>denied<\/code> depending on whether the user granted permission.<\/p>\n\n<p>Below is an image of an application requesting permission to display notifications in response to a user clicking the <strong>Enable Notifications<\/strong> button.<\/p>\n\n<h2>\n  \n  \n  Creating a Notification\n<\/h2>\n\n<p>The <code>Notification<\/code> constructor allows you to create and customize notifications to your specifications. It takes two arguments: a title and an optional configuration object. The <code>title<\/code> is a string that describes the notification, and the configuration object comprises some options to enhance the notification, such as a text body. For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">notification<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Notification<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Test<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n      <span class=\"na\">body<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Hey, this is a test notification<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n      <span class=\"na\">icon<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/imgs\/notification.png<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">});<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Most modern browsers close notifications on their own after a few seconds. Still, you can manually do this by calling the <code>close<\/code> method on <code>notification<\/code> and wrapping it in a <code>setTimeout<\/code> function.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nf\">setTimeout<\/span><span class=\"p\">(<\/span><span class=\"mi\">4000<\/span><span class=\"p\">,<\/span> <span class=\"nx\">notification<\/span><span class=\"p\">.<\/span><span class=\"nf\">close<\/span><span class=\"p\">())<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can learn more about the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Notifications_API\">Notification API in the MDN documentation<\/a>.<\/p>\n\n<h1>\n  \n  \n  The Geolocation API\n<\/h1>\n\n<p>The geolocation API is a built-in browser API that allows web applications to access a user\u2019s location, provided the user grants the appropriate permissions.<\/p>\n\n<p>Access to a user\u2019s location can be helpful in several scenarios, such as deliveries and displaying local content (weather, events, etc.).<\/p>\n\n<h2>\n  \n  \n  Working with the Geolocation Object\n<\/h2>\n\n<p>You can access the geolocation API throw the <code>navigator.geolocation<\/code> object. The geolocation API allows you to get a user\u2019s current position and watch a user\u2019s position using the <code>getCurrentPostion<\/code> and <code>watchPosition<\/code> methods, respectively.<\/p>\n\n<p>The <code>getCurrentPosition<\/code> is an asynchronous method that returns the user\u2019s current location. This method takes two callback functions as arguments: a success callback and an error callback. Additionally, it takes a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Geolocation\/getCurrentPosition#parameters\">configuration object<\/a> where specific options, like the accuracy level of the position, can be set.<\/p>\n\n<p>The success callback is executed when the user\u2019s position is successfully retrieved, while the error callback is executed when an error occurs.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nb\">navigator<\/span><span class=\"p\">.<\/span><span class=\"nx\">geolocation<\/span><span class=\"p\">.<\/span><span class=\"nf\">getCurrentPosition<\/span><span class=\"p\">(<\/span>\n  <span class=\"p\">(<\/span><span class=\"nx\">position<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">position<\/span><span class=\"p\">),<\/span>\n  <span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">),<\/span>\n  <span class=\"p\">{<\/span>\n    <span class=\"na\">enableHighAccuracy<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n    <span class=\"na\">timeout<\/span><span class=\"p\">:<\/span> <span class=\"mi\">5000<\/span><span class=\"p\">,<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The code block above returns a <code>GeolocationPosition<\/code> object with a <code>coords<\/code> and a <code>timestamp<\/code> property. With the <code>enableHighAccuracy<\/code> set to <code>true<\/code>, the coordinates returned will be more accurate. Setting the <code>timeout<\/code> property to 5000ms (5 seconds) will timeout the API and execute the error callback if fetching the location takes more than 5000ms.<\/p>\n\n<p>The <code>watchPosition<\/code> method updates the user\u2019s current location as the user moves or as more accurate geo-information arrives. This method returns an <code>ID<\/code> used to uniquely identify the requested position watcher and takes the exact arguments as the <code>getCurrentPosition<\/code> method.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">watcherID<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">navigator<\/span><span class=\"p\">.<\/span><span class=\"nx\">geolocation<\/span><span class=\"p\">.<\/span><span class=\"nf\">watchPosition<\/span><span class=\"p\">(<\/span>\n  <span class=\"p\">(<\/span><span class=\"nx\">position<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">position<\/span><span class=\"p\">),<\/span>\n  <span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The <code>watcherID<\/code> is used with the <code>clearWatch<\/code> method to stop monitoring a user\u2019s current location.<\/p>\n\n<p>Like so:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nb\">navigator<\/span><span class=\"p\">.<\/span><span class=\"nx\">geolocation<\/span><span class=\"p\">.<\/span><span class=\"nf\">clearWatch<\/span><span class=\"p\">(<\/span><span class=\"nx\">watcherID<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can learn more about <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Geolocation_API\">the geolocation API in the MDN documentation<\/a>.<\/p>\n\n<h1>\n  \n  \n  The History API\n<\/h1>\n\n<p>The history API is an API that allows developers to move forward or backward, move to a particular page in a user\u2019s history and modify the website\u2019s URL without refreshing the whole page.<\/p>\n\n<p>It is mainly used to modify the website\u2019s URL without refreshing the whole page in single-page applications (SPAs) using its <code>pushState<\/code> method.<\/p>\n\n<h2>\n  \n  \n  Moving Forward, Backward, and to a Specific Point\n<\/h2>\n\n<p>You can move forward in a user\u2019s history by calling the forward method on history.<\/p>\n\n<p>Like so:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">history<\/span><span class=\"p\">.<\/span><span class=\"nf\">forward<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>This command takes the users one step forward in their browsing history.<\/p>\n\n<p>You can move backward through a user\u2019s history by calling the back method on history.<\/p>\n\n<p>Like so:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">history<\/span><span class=\"p\">.<\/span><span class=\"nf\">back<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can move to a specific point in a user\u2019s history by calling the go method on history and passing the page\u2019s index as an argument.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"c1\">\/\/forward<\/span>\n<span class=\"nx\">history<\/span><span class=\"p\">.<\/span><span class=\"nf\">go<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<span class=\"c1\">\/\/backward<\/span>\n<span class=\"nx\">history<\/span><span class=\"p\">.<\/span><span class=\"nf\">go<\/span><span class=\"p\">(<\/span><span class=\"o\">-<\/span><span class=\"mi\">3<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The commands above take the users three steps forward and backward in their browsing history.<\/p>\n\n<p>Note: calling the <code>go<\/code> method without any argument or with <code>0<\/code> as an argument, will refresh the page.<\/p>\n\n<h2>\n  \n  \n  The pushState Method\n<\/h2>\n\n<p>The <code>pushState<\/code> method allows you to add entries to the user\u2019s web history without leaving or refreshing the page. As stated above, this is useful in SPAs that load additional data into the DOM in response to an event.<\/p>\n\n<p>It takes three arguments: <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History_API\/Working_with_the_History_API#the_pushstate_method\">state, title, and url<\/a>.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">let<\/span> <span class=\"nx\">stateObject<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">property<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">State Object<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"nx\">history<\/span><span class=\"p\">.<\/span><span class=\"nf\">pushState<\/span><span class=\"p\">(<\/span><span class=\"nx\">stateObject<\/span><span class=\"p\">,<\/span> <span class=\"kc\">null<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">state.html<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The <code>title<\/code> argument is set to <code>null<\/code> in the code block above because many modern browsers ignore it. Hence, conventionally set to <code>null<\/code>. When this method is called, the address bar will display <code>https:\/\/example.com\/state.html<\/code>, but the page won\u2019t reload. If the user clicks Back, the URL will change to <code>https:\/\/example.com\/<\/code> and a <code>popstate<\/code> event will be fired with a <code>null<\/code> state object.<\/p>\n\n<p>You can learn more about <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History_API\">the history API in the MDN documentation<\/a>.<\/p>\n\n<h1>\n  \n  \n  The Barcode Detection API\n<\/h1>\n\n<p>The barcode detection API is an experimental built-in API that detects linear and two-dimensional barcodes in images.<\/p>\n\n<p>Since this API is still experimental, you should check its <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Barcode_Detection_API#browser_compatibility\">browser compatibility<\/a> before using it in production environments.<\/p>\n\n<p>This feature is also not available in many browsers, so before you use it, you need to check if it is available in the browser. Like so:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">BarcodeDetector<\/span><span class=\"dl\">\"<\/span> <span class=\"k\">in<\/span> <span class=\"nb\">window<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">The Barcode Detector is supported!<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">The Barcode Detector is not supported in this browser<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Creating a Barcode Detector\n<\/h2>\n\n<p>You can create a barcode detector by creating an instance of the <code>BarcodeDetector<\/code> class and passing an array of the type of barcodes you want to scan for.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">barcodeDetector<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">BarcodeDetector<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">formats<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">qr_code<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">aztec<\/span><span class=\"dl\">\"<\/span><span class=\"p\">],<\/span>\n<span class=\"p\">});<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can get a list of all barcode formats supported by your browser by calling the <code>getSupportedFormats<\/code> method on <code>BarcodeDetector<\/code>. This asynchronous method returns an array of all the barcode formats supported by your browser.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">BarcodeDetector<\/span><span class=\"p\">.<\/span><span class=\"nf\">getSupportedFormats<\/span><span class=\"p\">().<\/span><span class=\"nf\">then<\/span><span class=\"p\">((<\/span><span class=\"nx\">supportedFormats<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">supportedFormats<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">});<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Scanning a Barcode\n<\/h2>\n\n<p>You can scan a barcode by calling the <code>detect<\/code> method on your <code>BarcodeDectector<\/code> instance. The detect method expects an image object as an argument. The image object can either be an element, a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Blob\">Blob<\/a>, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/ImageData\">ImageData<\/a>, or a <a href=\"https:\/\/udn.realityripple.com\/docs\/Web\/API\/CanvasImageSource\">CanvasImageSource<\/a>.<\/p>\n\n<p>The <code>detect<\/code> method returns an object with the following properties:<\/p>\n\n<ul>\n<li>\n<strong>boundingBox<\/strong>: This is an object containing the coordinates of the barcode.<\/li>\n<li>\n<strong>cornerPoints<\/strong>: This is an array containing the objects bearing the barcode coordinates: <code>leftTop<\/code>, <code>rightTop<\/code>, <code>rightBottom<\/code>, and <code>leftBottom<\/code>.<\/li>\n<li>\n<strong>format<\/strong>: This is a string depicting the detected format of the barcode.<\/li>\n<li>\n<strong>rawValue<\/strong>: This is a string depicting the value of the barcode.<\/li>\n<\/ul>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">imageElement<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nf\">getElementById<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">barcode<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">barcodeDetector<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">BarcodeDetector<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">formats<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">qr_code<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">aztec<\/span><span class=\"dl\">\"<\/span><span class=\"p\">],<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"nx\">barcodeDetector<\/span>\n  <span class=\"p\">.<\/span><span class=\"nf\">detect<\/span><span class=\"p\">(<\/span><span class=\"nx\">imageElement<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">.<\/span><span class=\"nf\">then<\/span><span class=\"p\">((<\/span><span class=\"nx\">barcodes<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">barcodes<\/span><span class=\"p\">.<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">((<\/span><span class=\"nx\">barcode<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">barcode<\/span><span class=\"p\">.<\/span><span class=\"nx\">rawValue<\/span><span class=\"p\">));<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"k\">catch<\/span><span class=\"p\">((<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">});<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can learn more about <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Barcode_Detection_API\">the barcode detection API in the MDN documentation<\/a>.<\/p>\n\n<p>Hope you enjoyed my article. Follow me on <a href=\"https:\/\/github.com\/ra1nbow1\">Github<\/a> &lt;3<\/p>\n\n","category":["webdev","javascript","api","programming"]},{"title":"React.js - Custom hooks","pubDate":"Mon, 19 Dec 2022 19:40:50 +0000","link":"https:\/\/dev.to\/rbs\/reactjs-custom-hooks-5abc","guid":"https:\/\/dev.to\/rbs\/reactjs-custom-hooks-5abc","description":"<p>The topic of hooks in React development is quite popular and has been analyzed more than once by various specialists. The purpose of our material is not so much to bring something new as to analyze a sufficiently important and relevant topic in the most accessible and understandable language, so that it does not cause difficulties even for beginners in the development of applications on React.<\/p>\n\n<p>First appeared in React version 16.8. The structure of applications based on the use of hooks was very pleasant to the community for its flexibility and simplicity, which allowed it to practically replace classes.<\/p>\n\n<h2>\n  \n  \n  It's easier with hooks!\n<\/h2>\n\n<p>Many newcomers were scared away by the classes with their cumbersomeness and less transparency. The mechanisms of state and reusable use looked much more complicated than in reality. The introduction of hooks has largely solved this problem and significantly increased the popularity of the library, which has been steadily growing for several years.<\/p>\n\n<h2>\n  \n  \n  React's main hooks out of the box\n<\/h2>\n\n<p>React out of the box contains several very important hooks.<\/p>\n\n<h3>\n  \n  \n  useState - manage the state in functional components\n<\/h3>\n\n<p>One of the most important hooks is useState. Its name immediately makes it clear what it is used for - it is responsible for the state. This hook allows you to influence the state like the this.setState() method. First of all, let's look at a simple example of its use:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">MyComponent<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">counter<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCounter<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">setCounter<\/span><span class=\"p\">(<\/span><span class=\"nx\">counter<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)}<\/span><span class=\"o\">&gt;<\/span>\n      <span class=\"o\">+<\/span><span class=\"mi\">1<\/span> <span class=\"nx\">to<\/span> <span class=\"nx\">the<\/span> <span class=\"nx\">previous<\/span> <span class=\"nx\">value<\/span>\n    <span class=\"o\">&lt;<\/span><span class=\"sr\">\/button<\/span><span class=\"err\">&gt;\n<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>In this example, after the functional element is declared, we call the useState method, passing it the default value:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">counter<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCounter<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The method returns an array of 2 elements. The 1st element is a state variable, the 2nd element contains a function to change this state. The button is set to the onClick event, which allows you to change the state by increasing the value by 1 from the previous one:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">setCounter<\/span><span class=\"p\">(<\/span><span class=\"nx\">counter<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  useContext - we transfer information to any levels of nesting\n<\/h3>\n\n<p>As a rule, the parent component shares data with children using props. However, there is a need to transfer this data not only to the nearest \"children\" of this component, but also to more nested components. Transmitting \"relatives\" along the entire chain is terribly inconvenient and can lead to mistakes. In this case, it is convenient to use useContext.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span><span class=\"nx\">createContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useContext<\/span><span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">react<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">MyContext<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">createContext<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">no data<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">Bookcase<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"err\">\u27e8<\/span><span class=\"nx\">MyContext<\/span><span class=\"p\">.<\/span><span class=\"nx\">Provider<\/span> <span class=\"nx\">value<\/span><span class=\"o\">=<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">\u0448\u043a\u0430\u0444 #1 <\/span><span class=\"dl\">\"<\/span><span class=\"err\">\u27e9<\/span>\n      <span class=\"err\">\u27e8<\/span><span class=\"nx\">Bookshelf<\/span> <span class=\"o\">\/<\/span><span class=\"err\">\u27e9<\/span>\n    <span class=\"err\">\u27e8<\/span><span class=\"o\">\/<\/span><span class=\"nx\">MyContext<\/span><span class=\"p\">.<\/span><span class=\"nx\">Provider<\/span><span class=\"err\">\u27e9<\/span>\n  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">Bookshelf<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"err\">\u27e8<\/span><span class=\"nx\">Book<\/span> <span class=\"o\">\/<\/span><span class=\"err\">\u27e9<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">Book<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">context<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useContext<\/span><span class=\"p\">(<\/span><span class=\"nx\">MyContext<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"s2\">`Book in is \"<\/span><span class=\"p\">${<\/span><span class=\"nx\">context<\/span><span class=\"p\">}<\/span><span class=\"s2\">\"`<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>In this example, thanks to the useContext hook, each book can have information about which cabinet it is located in, and there is no need to receive it from the direct parent (book shelf).<\/p>\n\n<h3>\n  \n  \n  useEffect - we implement lifecycle functionality\n<\/h3>\n\n<p>Used to simulate the lifecycle, as well as the componentDidMount, componentDidUpdate, componentWillUnmount methods do when using the React structure on classes. A callback function is passed as arguments, which performs the necessary actions and an array with variables, the change of which must be monitored and callback when they are changed.<\/p>\n\n<h3>\n  \n  \n  useRef - link variables directly to DOM\n<\/h3>\n\n<p>To access DOM elements directly in functional components, you must use useRef. In the example below, we bind the button to the buttonRef variable and can use this link in the callback function passed as the 1st argument in useRef.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">MyButton<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">buttonRef<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useRef<\/span><span class=\"p\">();<\/span>\n  <span class=\"nf\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">buttonRef<\/span><span class=\"p\">.<\/span><span class=\"nx\">current<\/span><span class=\"p\">.<\/span><span class=\"nx\">innerHTML<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[]);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"err\">\u27e8<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">ref<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">ref<\/span><span class=\"p\">}<\/span><span class=\"err\">\u27e9<\/span><span class=\"nx\">My<\/span> <span class=\"nx\">button<\/span><span class=\"err\">\u27e8<\/span><span class=\"o\">\/<\/span><span class=\"nx\">button<\/span><span class=\"err\">\u27e9<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  More hooks!\n<\/h2>\n\n<p>useReducer: allows you to store the status value regardless of nesting, is an analogue of Redux.<\/p>\n\n<p>useMemo: allows you to store the value and recalculate only when constraints change.<\/p>\n\n<p>useCallback: used to memoize functions, avoids unnecessary rendering and re-creation of functions. Very useful for optimization.<\/p>\n\n<h2>\n  \n  \n  We're writing our own hook\n<\/h2>\n\n<p>In essence, hooks are common functions, the name of which begins with the prefix \"use\". They can use other hooks, accept arguments and return the result.<\/p>\n\n<p>It is convenient to create your own hooks when you need to learn the logic that is often used in different components of the application. It is necessary to remember about important restrictions for hooks: you can't call inside conditional constructions and loops - this will cause an error in the application.<\/p>\n\n<p>Let's look at an example from the official react documentation. It is interesting because it describes an example of creating a useReducer hook using an existing useState.<\/p>\n\n<p>Let's say we work with a component that has a fairly developed state management logic depending on their type. In this case, useState is not very convenient to use with centralized state management logic and Redux-reducer is more suitable:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">todosReducer<\/span><span class=\"p\">(<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"nx\">action<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">switch <\/span><span class=\"p\">(<\/span><span class=\"nx\">action<\/span><span class=\"p\">.<\/span><span class=\"nx\">type<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">case<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">add<\/span><span class=\"dl\">'<\/span><span class=\"p\">:<\/span>\n      <span class=\"k\">return<\/span> <span class=\"p\">[...<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n        <span class=\"na\">text<\/span><span class=\"p\">:<\/span> <span class=\"nx\">action<\/span><span class=\"p\">.<\/span><span class=\"nx\">text<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">completed<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span>\n      <span class=\"p\">}];<\/span>\n    <span class=\"c1\">\/\/ ... other actions ...<\/span>\n    <span class=\"nl\">default<\/span><span class=\"p\">:<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">state<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Our hook will look like this (simplified):<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">useReducer<\/span><span class=\"p\">(<\/span><span class=\"nx\">reducer<\/span><span class=\"p\">,<\/span> <span class=\"nx\">initialState<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setState<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(<\/span><span class=\"nx\">initialState<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"kd\">function<\/span> <span class=\"nf\">dispatch<\/span><span class=\"p\">(<\/span><span class=\"nx\">action<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">nextState<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">reducer<\/span><span class=\"p\">(<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"nx\">action<\/span><span class=\"p\">)<\/span>\n    <span class=\"nf\">setState<\/span><span class=\"p\">(<\/span><span class=\"nx\">nextState<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"nx\">dispatch<\/span><span class=\"p\">]<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Here we accept as parameters - a reworker function responsible for the log of state change, initial state, and return the current state and function to change it. At the same time, we can very easily modify the logic of changing states by adding\/changing types in the todosReducer function. After that, it is convenient to use this logic in your component:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">Todos<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">todos<\/span><span class=\"p\">,<\/span> <span class=\"nx\">dispatch<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useReducer<\/span><span class=\"p\">(<\/span><span class=\"nx\">todosReducer<\/span><span class=\"p\">,<\/span> <span class=\"p\">[])<\/span>\n  <span class=\"kd\">function<\/span> <span class=\"nf\">handleAddClick<\/span><span class=\"p\">(<\/span><span class=\"nx\">text<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">dispatch<\/span><span class=\"p\">({<\/span> <span class=\"na\">type<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">add<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">text<\/span> <span class=\"p\">})<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Hooks can be used for a wide variety of purposes. Let's look at an example of a hook for working with local browser storage:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">getStorageValue<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">defaultValue<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">saved<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">localStorage<\/span><span class=\"p\">.<\/span><span class=\"nf\">getItem<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">initial<\/span> <span class=\"o\">=<\/span> <span class=\"o\">!<\/span><span class=\"nx\">saved<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">saved<\/span> <span class=\"o\">===<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">undefined<\/span><span class=\"dl\">'<\/span> <span class=\"p\">?<\/span> <span class=\"kc\">null<\/span> <span class=\"p\">:<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">parse<\/span><span class=\"p\">(<\/span><span class=\"nx\">saved<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">initial<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">defaultValue<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span>  <span class=\"kd\">function<\/span> <span class=\"nf\">useLocalStorage<\/span> <span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">defaultValue<\/span><span class=\"p\">){<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setValue<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useState<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">getStorageValue<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">defaultValue<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">});<\/span>\n\n  <span class=\"nf\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"o\">=<\/span><span class=\"err\">\u27e9<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">localStorage<\/span><span class=\"p\">.<\/span><span class=\"nf\">setItem<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">value<\/span><span class=\"p\">));<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">]);<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setValue<\/span><span class=\"p\">];<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>We defined the function of working with localStorage by writing our own logic for obtaining primary data from the repository. Then we created a hook that initializes the state using the result of this function. We also use useEffect to write to localStorage when changing the value of the key or value variables. In our component, we can use the hook in this way:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">storageData<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setStorageData<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">useLocalStorage<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">my-data<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>So, we managed to link data in the state with the data in the local browser storage.<\/p>\n\n<p>That's all for now, I hope this article helped make understanding the topic of hooks easier for you!<\/p>\n\n<p>Thanks for reading. Leave your comments below and follow my <a href=\"https:\/\/github.com\/ra1nbow1\">GitHub<\/a> &lt;3<\/p>\n\n","category":["webdev","javascript","react","tutorial"]},{"title":"5 ways to use the reduce method in JS","pubDate":"Fri, 07 Oct 2022 21:59:10 +0000","link":"https:\/\/dev.to\/ra1nbow1\/5-ways-to-use-the-reduce-method-in-js-1k8h","guid":"https:\/\/dev.to\/ra1nbow1\/5-ways-to-use-the-reduce-method-in-js-1k8h","description":"<p>The modern JavaScript standard provides many methods for \"smart\" brute force for arrays. Among the most popular are forEach, for or for...of. If you need to iterate over the array and return data for each element, map is suitable.<\/p>\n\n<p>In case you need to walk through the array and, for example, summarize all the values, find the average or perform any intermediate actions, it is better to use the reduce method.<\/p>\n\n<p>In what scenarios it can be used - in this article.<\/p>\n\n<blockquote>\n<p><strong>Reduce<\/strong> collapses the array to one value (reducets). This value can be any type of data - both primitive and composite, for example, an array.<\/p>\n<\/blockquote>\n\n<p>The method accepts two arguments:<\/p>\n\n<ul>\n<li>callback function performed to run each element in the array;<\/li>\n<li>initial value of initialValue.\nCallback also accepts two arguments: accumulator, which returns the callback function after visiting another element, and the current element in the currentValue loop.<\/li>\n<\/ul>\n\n<p>Let's consider several non-obvious applications of the reduce method that will help to adhere to the write less, do more principle.<\/p>\n\n<h2>\n  \n  \n  Minimum and maximum value in the array\n<\/h2>\n\n<p>To find the minimum and maximum values, you can use the Math API, for example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">array<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">11<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">21<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">];<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">max<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">Math<\/span><span class=\"p\">.<\/span><span class=\"nf\">max<\/span><span class=\"p\">(...<\/span><span class=\"nx\">array<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ 21<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">min<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">Math<\/span><span class=\"p\">.<\/span><span class=\"nf\">min<\/span><span class=\"p\">(...<\/span><span class=\"nx\">array<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ -11<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>But when using large arrays (~10^7), you may encounter errors. You can eliminate these problems and get the desired result using the reduce method.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">array<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">11<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">21<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">];<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">max<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">array<\/span><span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">((<\/span><span class=\"nx\">max<\/span><span class=\"p\">,<\/span> <span class=\"nx\">num<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">max<\/span> <span class=\"o\">&gt;<\/span> <span class=\"nx\">num<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">max<\/span> <span class=\"p\">:<\/span> <span class=\"nx\">num<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ 21<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">min<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">array<\/span><span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">((<\/span><span class=\"nx\">min<\/span><span class=\"p\">,<\/span> <span class=\"nx\">num<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">min<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">num<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">min<\/span> <span class=\"p\">:<\/span> <span class=\"nx\">num<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ -11<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You may need to parse the parameters in the GET URL and add them to an object.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">parseQuery<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">url<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">URL<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/ranbow1.xyz?name=hello&amp;title=world<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">search<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">url<\/span><span class=\"p\">.<\/span><span class=\"nx\">search<\/span><span class=\"p\">;<\/span>\n  <span class=\"kd\">let<\/span> <span class=\"nx\">query<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{};<\/span>\n  <span class=\"nx\">search<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">slice<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">&amp;<\/span><span class=\"dl\">\"<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">((<\/span><span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">item<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">=<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n      <span class=\"nx\">query<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">decodeURIComponent<\/span><span class=\"p\">(<\/span><span class=\"nx\">value<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">query<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<span class=\"c1\">\/\/ {name: \"hello\", title: \"world\"}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>But using the reduce method, everything becomes clearer and more predictable:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">parseQuery<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">url<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">URL<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">https:\/\/ra1nbow.xyz?name=hello&amp;title=world<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">search<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">url<\/span><span class=\"p\">.<\/span><span class=\"nx\">search<\/span><span class=\"p\">;<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">search<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/<\/span><span class=\"se\">(<\/span><span class=\"sr\">^<\/span><span class=\"se\">?)<\/span><span class=\"sr\">|<\/span><span class=\"se\">(<\/span><span class=\"sr\">&amp;$<\/span><span class=\"se\">)<\/span><span class=\"sr\">\/g<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">&amp;<\/span><span class=\"dl\">\"<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">((<\/span><span class=\"nx\">query<\/span><span class=\"p\">,<\/span> <span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">item<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">=<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n      <span class=\"nx\">query<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">decodeURIComponent<\/span><span class=\"p\">(<\/span><span class=\"nx\">value<\/span><span class=\"p\">);<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">query<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">},<\/span> <span class=\"p\">{});<\/span>\n<span class=\"p\">};<\/span>\n<span class=\"c1\">\/\/ {name: \"hello\", title: \"world\"}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Here's how it works:<\/p>\n\n<ol>\n<li>Get search parameters from the URL - <a href=\"https:\/\/ra1nbow.xyz\">https:\/\/ra1nbow.xyz<\/a>? name=hello&amp;title=world\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">search<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">url<\/span><span class=\"p\">.<\/span><span class=\"nx\">search<\/span><span class=\"p\">;<\/span>  <span class=\"c1\">\/\/ ?name=hello&amp;title=world<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<ol>\n<li>Remove unnecessary characters\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">search<\/span><span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/<\/span><span class=\"se\">(<\/span><span class=\"sr\">^<\/span><span class=\"se\">?)<\/span><span class=\"sr\">|<\/span><span class=\"se\">(<\/span><span class=\"sr\">&amp;$<\/span><span class=\"se\">)<\/span><span class=\"sr\">\/g<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">);<\/span>\n<span class=\"c1\">\/\/?name=hello&amp;title=world =&gt; name=hello&amp;title=world<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<ol>\n<li>We use reduce to collect parameters into an object<\/li>\n<\/ol>\n\n<h2>\n  \n  \n  Deserialization of parameters\n<\/h2>\n\n<p>In this example, the situation is the opposite. If you need to add a set of parameters to the link, it is not very convenient to use concatenation (gluing lines), especially if there are tens or hundreds of such parameters. Because of this, the readability of the code drops significantly, the line size increases with each new parameter, which creates difficulties for further support.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">searchObj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">hello<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">world<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">};<\/span> <span class=\"c1\">\/\/ many others parameters<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">link<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">`https:\/\/ra1nbow.xyz?name=<\/span><span class=\"p\">${<\/span><span class=\"nx\">searchObj<\/span><span class=\"p\">.<\/span><span class=\"nx\">name<\/span><span class=\"p\">}<\/span><span class=\"s2\">&amp;age=<\/span><span class=\"p\">${<\/span><span class=\"nx\">searchObj<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span><span class=\"p\">}<\/span><span class=\"s2\">`<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>You can correct the situation using the reduce method. First of all, we write the function:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">stringifySearch<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">search<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{})<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">entries<\/span><span class=\"p\">(<\/span><span class=\"nx\">search<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">(<\/span>\n      <span class=\"p\">(<\/span><span class=\"nx\">t<\/span><span class=\"p\">,<\/span> <span class=\"nx\">v<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>     <span class=\"s2\">`<\/span><span class=\"p\">${<\/span><span class=\"nx\">t<\/span><span class=\"p\">}${<\/span><span class=\"nx\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]}<\/span><span class=\"s2\">=<\/span><span class=\"p\">${<\/span><span class=\"nf\">encodeURIComponent<\/span><span class=\"p\">(<\/span><span class=\"nx\">v<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">])}<\/span><span class=\"s2\">&amp;`<\/span><span class=\"p\">,<\/span>\n      <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">search<\/span><span class=\"p\">).<\/span><span class=\"nx\">length<\/span> <span class=\"p\">?<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">?<\/span><span class=\"dl\">'<\/span> <span class=\"p\">:<\/span> <span class=\"dl\">''<\/span>\n    <span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/&amp;$\/<\/span><span class=\"p\">,<\/span> <span class=\"dl\">''<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Next, we take the object from the previously described example and apply it:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">searchObj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">hello<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">title<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">world<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">};<\/span> <span class=\"c1\">\/\/ many others parameters<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">search<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">stringifySearch<\/span><span class=\"p\">(<\/span><span class=\"nx\">searchObj<\/span><span class=\"p\">);<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">link<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">`https:\/\/ra1nbow.xyz<\/span><span class=\"p\">${<\/span><span class=\"nx\">search<\/span><span class=\"p\">}<\/span><span class=\"s2\">`<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ https:\/\/ra1nbow.xyz?name=hello&amp;title=world<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Now you don't have to worry that when you change the object, the subsequent code will not work correctly.<\/p>\n\n<h2>\n  \n  \n  Selection of unique elements of the array\n<\/h2>\n\n<p>It's simple: we go through the array and look for if there is already such a meaning in it. If not, we add it, and if there is one, we go further. Thus, the output will be an array of only unique values.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">someArray<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">11<\/span><span class=\"p\">];<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">uniqueArray<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">someArray<\/span><span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">(<\/span>\n  <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">,<\/span> <span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">.<\/span><span class=\"nf\">includes<\/span><span class=\"p\">(<\/span><span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">acc<\/span> <span class=\"p\">:<\/span> <span class=\"p\">[...<\/span><span class=\"nx\">acc<\/span><span class=\"p\">,<\/span> <span class=\"nx\">item<\/span><span class=\"p\">]),<\/span>\n  <span class=\"p\">[]<\/span>\n<span class=\"p\">);<\/span> <span class=\"c1\">\/\/ [1, 2, -1, 10, 11]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Determining the number of identical elements of the array\n<\/h2>\n\n<p>To get the number of each element in the array, we additionally use Map - this is a collection of key value, as well as Object.<\/p>\n\n<p>The main difference is that in Map we will be able to work with an array that uses values of different types (numbers\/rows).<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">count<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">array<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">array<\/span><span class=\"p\">.<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">(<\/span>\n    <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">,<\/span> <span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">.<\/span><span class=\"nf\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">item<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">item<\/span><span class=\"p\">)<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">),<\/span> <span class=\"nx\">acc<\/span><span class=\"p\">),<\/span>\n    <span class=\"k\">new<\/span> <span class=\"nc\">Map<\/span><span class=\"p\">()<\/span>\n  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">array<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">6<\/span><span class=\"p\">];<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nf\">count<\/span><span class=\"p\">(<\/span><span class=\"nx\">array<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ Map(6) {1 =&gt; 2, 2 =&gt; 2, -1 =&gt; 1, 0 =&gt; 2, 10 =&gt; 2, 6 =&gt; 1}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Getting multiple object properties\n<\/h2>\n\n<p>Such a scenario quite often occurs in everyday work. Let's look at an example.<\/p>\n\n<p>We have an object with many properties:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">obj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">a<\/span><span class=\"p\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">b<\/span><span class=\"p\">:<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">c<\/span><span class=\"p\">:<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">d<\/span><span class=\"p\">:<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">e<\/span><span class=\"p\">:<\/span> <span class=\"mi\">5<\/span>\n  <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>We want to get some properties of the previous object and create a new one:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">newObj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">a<\/span><span class=\"p\">:<\/span> <span class=\"nx\">obj<\/span><span class=\"p\">.<\/span><span class=\"nx\">a<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">b<\/span><span class=\"p\">:<\/span> <span class=\"nx\">obj<\/span><span class=\"p\">.<\/span><span class=\"nx\">b<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">c<\/span><span class=\"p\">:<\/span> <span class=\"nx\">obj<\/span><span class=\"p\">.<\/span><span class=\"nx\">c<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">d<\/span><span class=\"p\">:<\/span> <span class=\"nx\">obj<\/span><span class=\"p\">.<\/span><span class=\"nx\">d<\/span>\n  <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>It doesn't seem to be very effective, does it?<\/p>\n\n<p>Let's write a small helper that will make it easier for us to solve the problem:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">getObjectKeys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">obj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{},<\/span> <span class=\"nx\">keys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[])<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">obj<\/span><span class=\"p\">).<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">(<\/span>\n    <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">keys<\/span><span class=\"p\">.<\/span><span class=\"nf\">includes<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"p\">(<\/span><span class=\"nx\">acc<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">obj<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]),<\/span> <span class=\"nx\">acc<\/span><span class=\"p\">),<\/span>\n    <span class=\"p\">{}<\/span>\n  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>And, of course, let's check how it all works:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">obj<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">a<\/span><span class=\"p\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">b<\/span><span class=\"p\">:<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">c<\/span><span class=\"p\">:<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">d<\/span><span class=\"p\">:<\/span> <span class=\"mi\">4<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">e<\/span><span class=\"p\">:<\/span> <span class=\"mi\">5<\/span>\n  <span class=\"c1\">\/\/ ...<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">newObj<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">getObjectKeys<\/span><span class=\"p\">(<\/span><span class=\"nx\">obj<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">a<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">b<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">c<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">d<\/span><span class=\"dl\">'<\/span> <span class=\"p\">])<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">newObj<\/span><span class=\"p\">)<\/span> <span class=\"c1\">\/\/ {a: 1, b: 2, c: 3, d: 4}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>This is only part of the possible scenarios for applying the method in everyday tasks. I hope you found something interesting for yourself.<\/p>\n\n<p>Thank you for your attention and happy coding!<\/p>\n\n<p><a href=\"https:\/\/github.com\/ra1nbow1\">My Github &lt;3<\/a><\/p>\n\n","category":["javascript","webdev","tutorial","productivity"]},{"title":"5+5=? Converting values to a string or number in JavaScript","pubDate":"Sat, 11 Jun 2022 21:24:23 +0000","link":"https:\/\/dev.to\/ra1nbow1\/55-converting-values-to-a-string-or-number-in-javascript-43cc","guid":"https:\/\/dev.to\/ra1nbow1\/55-converting-values-to-a-string-or-number-in-javascript-43cc","description":"<p>In JavaScript, data can be converted automatically or using functions. In this article, we will learn how data conversion methods work in JS and why adding 5 and 5 together can get 55 instead of 10.<\/p>\n\n<p>Let's analyze the example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">5<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ number<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">b<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">5<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ string<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span> \n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ 55<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">))<\/span> <span class=\"c1\">\/\/ string<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>When we add <code>5<\/code> and <code>5<\/code>, we expect to see the output \u2014 <code>10<\/code>. However, we get <code>55<\/code> and see that the data type is not a number, but a string.<\/p>\n\n<p>JavaScript automatically converted the variable <code>a<\/code> to a string and concatenated it with the variable <code>b<\/code> into a single string.<\/p>\n\n<p>To make the data type expected by the developer, use conversion functions. Let's look at them in detail.<\/p>\n\n<h3>\n  \n  \n  Converting to a string in JavaScript\n<\/h3>\n\n<p>To convert a number to a string, use the function <code>String()<\/code>.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">5<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ number<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">String<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ convert the variable \u0430 to string<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/string<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Converting to a number in JavaScript\n<\/h3>\n\n<p>To convert data to a number, use the function <code>Number()<\/code>. Let's try converting a string value <code>5<\/code> to a number.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">5<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ string<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">Number<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ convert the variable \u0430 to number<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/number<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>If you use strings in mathematical expressions, JavaScript automatically converts variables to numbers.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">5<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ string<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">b<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">5<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ string<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">\/<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span> \n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">);<\/span><span class=\"c1\">\/\/ print 1, that is expected by dividing 5 on 5<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ number<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Logical conversion to JavaScript\n<\/h3>\n\n<p>For logical conversion, use the function <code>Boolean()<\/code>.<\/p>\n\n<p>Types <code>empty string<\/code>,<code>NaN<\/code>, <code>undefined<\/code>, <code>null<\/code> \u2014 is converted to false.<\/p>\n\n<p>All other data, such as numbers and strings, is converted to true.<\/p>\n\n<p>For example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">null<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nc\">Boolean<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ false<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">0<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nc\">Boolean<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/true<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\"> <\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ space<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nc\">Boolean<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ true<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">var<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"\"<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ empty, without spaces and other characters<\/span>\n<span class=\"nf\">alert<\/span><span class=\"p\">(<\/span><span class=\"nc\">Boolean<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">));<\/span> <span class=\"c1\">\/\/ false<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Let's sum up the results\n<\/h3>\n\n<p>JavaScript can transform data automatically:<\/p>\n\n<ul>\n<li>numbers are converted to strings if they are used in expressions with a string;<\/li>\n<li>if the strings contain numbers and mathematical operations are performed with them, they are converted to numbers.<\/li>\n<\/ul>\n\n<p>For conversion, use the functions:<\/p>\n\n<ol>\n<li>\n<code>String()<\/code> - converts data to numbers.<\/li>\n<li>\n<code>Number()<\/code> - converts data to strings.<\/li>\n<li>\n<code>Boolean()<\/code> - converts data to boolean values true or false.<\/li>\n<\/ol>\n\n","category":["programming","javascript","tutorial","beginners"]},{"title":"8 ways to add an element to the beginning of a list and string in Python","pubDate":"Fri, 03 Jun 2022 23:01:19 +0000","link":"https:\/\/dev.to\/ra1nbow1\/8-ways-to-add-an-element-to-the-beginning-of-a-list-and-string-in-python-925","guid":"https:\/\/dev.to\/ra1nbow1\/8-ways-to-add-an-element-to-the-beginning-of-a-list-and-string-in-python-925","description":"<p>Let's look at different methods for adding elements to the beginning of a list and string: concatenation, insert, append, extend, rjust, and f-strings.<\/p>\n\n<h2>\n  \n  \n  How to add an item to the top of a Python list: 4 methods\n<\/h2>\n\n<p>Lists in Python are mutable and ordered data structures designed to store a group of values. If you need to insert an element in the first position of an existing list during the program execution, you can use one of the methods described below.<\/p>\n\n<h3>\n  \n  \n  Method 1: insert\n<\/h3>\n\n<p>This method is implemented using the built-in <strong>insert()<\/strong> method of lists. This method works with any type of data and allows you to insert the desired element at any position in the existing list, including the first one.<\/p>\n\n<p>The <strong>insert()<\/strong> method takes two parameters \u2013 the index (position) at which the element is to be inserted, and the element itself. Counting positions in Python starts from zero \u2013 Accordingly, to insert an element at the beginning of the list , you need to specify <code>0<\/code>, and not, as the first parameter <code>1<\/code>.<\/p>\n\n<p>Let's take an example. Suppose we have a list <code>[1, 2, 3]<\/code> where we want to insert the number <strong>5<\/strong> at the beginning. Use the <strong>insert()<\/strong> method:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">arr<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">arr<\/span><span class=\"p\">.<\/span><span class=\"nf\">insert<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">5<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Result:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Method 2: Concatenation\n<\/h3>\n\n<p>Using concatenation (addition), you can also insert the desired element at the beginning of the list. However, this requires that the element is presented as a list:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">arr<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">([<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span> <span class=\"o\">+<\/span> <span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result will be the same as in the first method:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Method 3: The append method\n<\/h3>\n\n<p>By default, this method expands an existing list by adding an element to the end. But nothing prevents you from expanding the list consisting of a single element:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">arr<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result when using <strong>append()<\/strong> is different \u2013 you will get a nested list:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The desired element, however, gets an index <code>0<\/code>, so the goal is completed. In addition, when solving some tasks, you may need to create a nested list, so this method has the right to live.<\/p>\n\n<h3>\n  \n  \n  Method 4: extend method\n<\/h3>\n\n<p>The extend() method is similar to append () \u2013 with the difference that it preserves the\" one-dimensionality \" of the list:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">arr<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span><span class=\"p\">.<\/span><span class=\"nf\">extend<\/span><span class=\"p\">(<\/span><span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">num<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result is a regular, non-nested list:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Note that one-dimensionality is preserved even if the element to be placed at the beginning of the list is itself a list consisting of several elements:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">arr<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">6<\/span><span class=\"p\">,<\/span> <span class=\"mi\">7<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">num<\/span><span class=\"p\">.<\/span><span class=\"nf\">extend<\/span><span class=\"p\">(<\/span><span class=\"n\">arr<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">num<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Result:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">,<\/span> <span class=\"mi\">6<\/span><span class=\"p\">,<\/span> <span class=\"mi\">7<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  4 ways to add an element to the beginning of a string in Python\n<\/h2>\n\n<p>Strings in Python are an immutable data type <code>str<\/code>, and represent sequences of different characters. Since the lines do not change, you can only add elements to the beginning of the sequence by creating a new line.<\/p>\n\n<h3>\n  \n  \n  Method 1: Concatenation\n<\/h3>\n\n<p>Strings in Python can be concatenated (the result will be a new line). Let's look at the example of inserting a sign +at the beginning of a string containing an abstract mobile number:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">el<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">+<\/span><span class=\"sh\">'<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">123456<\/span><span class=\"sh\">'<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">el<\/span> <span class=\"o\">+<\/span> <span class=\"n\">num<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The operation results in a new line:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"o\">+<\/span><span class=\"mi\">123456<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Method 2: Using the f-string\n<\/h3>\n\n<p>You can also use the <strong>f-string to insert an element at the beginning of a line<\/strong>:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">el<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">+<\/span><span class=\"sh\">'<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">1337<\/span><span class=\"sh\">'<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">el<\/span><span class=\"si\">}{<\/span><span class=\"n\">num<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result will be similar to the first method:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"o\">+<\/span><span class=\"mi\">1337<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Method 3: Converting to a list\n<\/h3>\n\n<p>If you need to insert an element at a specific position in the string, including at the beginning, you can use the <strong>join()<\/strong> method to convert the string to a list and merge the list into a string.:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">el<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">+<\/span><span class=\"sh\">'<\/span>\n<span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">list<\/span><span class=\"p\">(<\/span><span class=\"sh\">'<\/span><span class=\"s\">9876<\/span><span class=\"sh\">'<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">(<\/span><span class=\"n\">num<\/span><span class=\"p\">).<\/span><span class=\"nf\">insert<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"n\">el<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">''<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"n\">num<\/span><span class=\"p\">))<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result will be the same:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"o\">+<\/span><span class=\"mi\">9876<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Method 4: Using rjust\n<\/h3>\n\n<p>The <strong>rjust()<\/strong> method is used to align the line to the right edge. As parameters, it accepts the length of a new line and the character that will be used to fill in empty positions. By default, a space is used as a placeholder, but nothing prevents you from selecting a sign <code>+<\/code>:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">num<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">5678<\/span><span class=\"sh\">\"<\/span>\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">num<\/span><span class=\"p\">.<\/span><span class=\"nf\">rjust<\/span><span class=\"p\">(<\/span><span class=\"mi\">12<\/span><span class=\"p\">,<\/span> <span class=\"sh\">'<\/span><span class=\"s\">+<\/span><span class=\"sh\">'<\/span><span class=\"p\">))<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The result is the desired string with the required character inserted at the beginning:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"o\">+<\/span><span class=\"mi\">5678<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Let's sum up the results\n<\/h2>\n\n<p>We've covered eight simple and practical ways to add the desired element to the beginning of a Python list and string. Do you know any other interesting ways to insert elements? Share it with us in the comments.<\/p>\n\n","category":["python","tutorial","programming"]},{"title":"5 cool JavaScript features that most developers don't know about","pubDate":"Tue, 04 Jan 2022 08:55:10 +0000","link":"https:\/\/dev.to\/ra1nbow1\/5-cool-javascript-features-that-most-developers-dont-know-about-5b7f","guid":"https:\/\/dev.to\/ra1nbow1\/5-cool-javascript-features-that-most-developers-dont-know-about-5b7f","description":"<p>You can use JavaScript to do the same thing in different ways. With the release of each new ECMAScript specification, new methods and operators are added to make the code shorter and more readable.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbm3z5isc5qqlqu2d31c0.png\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbm3z5isc5qqlqu2d31c0.png\" alt=\"Code\"><\/a><\/p>\n\n<h2>\n  \n  \n  1. Object.entries\n<\/h2>\n\n<p>Most developers use the <strong>Object.keys<\/strong> method to iterate through an object. This method returns only an array of object keys, not values. You can use <strong>Object.entries<\/strong> to get both the key and the value.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">person<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">Nick<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">age<\/span><span class=\"p\">:<\/span> <span class=\"mi\">27<\/span>\n<span class=\"p\">};<\/span>\n<span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">person<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ ['name', 'age']<\/span>\n<span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">entries<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ [['name', 'Nick'], ['age', 27]]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>To iterate over an object, we can do the following::<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">person<\/span><span class=\"p\">).<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">((<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"s2\">`<\/span><span class=\"p\">${<\/span><span class=\"nx\">key<\/span><span class=\"p\">}<\/span><span class=\"s2\"> is <\/span><span class=\"p\">${<\/span><span class=\"nx\">person<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]}<\/span><span class=\"s2\">`<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">});<\/span>\n<span class=\"c1\">\/\/ using records to get the key and value<\/span>\n<span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nf\">entries<\/span><span class=\"p\">(<\/span><span class=\"nx\">person<\/span><span class=\"p\">).<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">(([<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">])<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"s2\">`<\/span><span class=\"p\">${<\/span><span class=\"nx\">key<\/span><span class=\"p\">}<\/span><span class=\"s2\"> is <\/span><span class=\"p\">${<\/span><span class=\"nx\">value<\/span><span class=\"p\">}<\/span><span class=\"s2\">`<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">});<\/span>\n<span class=\"c1\">\/\/ expected result:<\/span>\n<span class=\"c1\">\/\/ name is Nick<\/span>\n<span class=\"c1\">\/\/ age is 27<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Both approaches described above return the same result, but <strong>Object.entries<\/strong> makes it easy to get a key-value pair.<\/p>\n\n<h2>\n  \n  \n  2. The replaceAll method\n<\/h2>\n\n<p>In JavaScript, to replace all occurrences of a string with another string, we need to use a regular expression like the following:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">str<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">Red-Green-Blue<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n\n<span class=\"c1\">\/\/ replaces only the first entry<\/span>\n\n<span class=\"nx\">str<\/span><span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">-<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\"> <\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ Red Green-Blue<\/span>\n\n<span class=\"c1\">\/\/ use a regular expression to replace all entries<\/span>\n<span class=\"nx\">str<\/span><span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sr\">\/<\/span><span class=\"se\">\\-<\/span><span class=\"sr\">\/g<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\"> <\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ Red Green Blue<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>But in ES12, a new replaceAll <strong>method was added to String.prototype<\/strong>, which replaces all occurrences of the string with another string value:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nx\">str<\/span><span class=\"p\">.<\/span><span class=\"nf\">replaceAll<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">-<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\"> <\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ Red Green Blue<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  3. Numeric separator\n<\/h2>\n\n<p>You can use the underscore \"_\" as a numeric separator to simplify counting the number of zeros in a number.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"c1\">\/\/ less readable<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">billion<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1000000000<\/span><span class=\"p\">;<\/span>\n<span class=\"c1\">\/\/ more readable<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">readableBillion<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1000<\/span><span class=\"nx\">_000_000<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">readableBillion<\/span><span class=\"p\">)<\/span> <span class=\"c1\">\/\/ returns 1000000000<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The separator can also be used with BigInt numbers, as in the following example:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">trillion<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1000<\/span><span class=\"nx\">_000_000_000n<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">trillion<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ 1000000000000<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>This makes the number more readable.<\/p>\n\n<h2>\n  \n  \n  4. document.designMode\n<\/h2>\n\n<p>Linked to front-end JavaScript, <strong>design Mode<\/strong> lets you edit any content on the page. Just open the browser console and enter the following:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nx\">designMode<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">on<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p><iframe src=\"https:\/\/player.vimeo.com\/video\/662198650\" width=\"710\" height=\"399\">\n<\/iframe>\n<\/p>\n\n<p>This is useful for designers, as they don't need to change something in the code every time to match the changes on the screen.<\/p>\n\n<h2>\n  \n  \n  5. Logical assignment operator\n<\/h2>\n\n<p>Logical assignment operators are a combination of the logical operators <strong>&amp;&amp;, ||, ??<\/strong> and the assignment operator <strong>=<\/strong>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">b<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">2<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">&amp;&amp;=<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ returns 2<\/span>\n<span class=\"c1\">\/\/ the above statement is equivalent to a &amp;&amp; (a = b);<\/span>\n<span class=\"c1\">\/\/ OR another way<\/span>\n<span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">b<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Here it checks whether the value of <strong>a<\/strong> matches true, and if so, we update its value. The same can be done with the logical <strong>OR \/\/<\/strong> operator.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">null<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">b<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">3<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">||=<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ returns 3<\/span>\n<span class=\"c1\">\/\/ the above statement is equivalent to<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">||<\/span> <span class=\"p\">(<\/span><span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">b<\/span><span class=\"p\">);<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>And also with the help of an operator <strong>??<\/strong>:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">null<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">b<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">3<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">a<\/span> <span class=\"o\">??=<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ returns 3<\/span>\n<span class=\"c1\">\/\/ the above statement is equivalent to<\/span>\n<span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">null<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">b<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The operator <strong>??<\/strong> checks only for null or undefined values.<\/p>\n\n<p>Note that logical assignment operators have been added since <strong>ES 12\/ES 2021<\/strong>.<\/p>\n\n<h2>\n  \n  \n  Conclusion\n<\/h2>\n\n<p>These tricks and features can speed up the developer's work, and their use is not only necessary, but also useful. Continue to explore the hidden features of the language, learn all sorts of tricks and improve your skills.<\/p>\n\n","category":["javascript","webdev","programming","tutorial"]},{"title":"Best JavaScript Books of 2021","pubDate":"Sat, 25 Dec 2021 19:33:56 +0000","link":"https:\/\/dev.to\/ra1nbow1\/best-javascript-books-of-2021-4b6j","guid":"https:\/\/dev.to\/ra1nbow1\/best-javascript-books-of-2021-4b6j","description":"<p>JS is still one of the most popular programming languages, if not the most popular. At least in the field of web development, you can't do without it. Not surprisingly, new books on JavaScript are constantly being published, as well as old ones being re-published.<\/p>\n\n<p>In this article, we have collected several such books that will be published in 2021. Our selection includes books both for beginners and experienced programmers.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.oreilly.com\/library\/view\/modern-javascript-for\/9780136502166\/\" rel=\"noopener noreferrer\">Modern JavaScript for the impatient<\/a>\n<\/h2>\n\n<p>Author: Kay S. Horstman. Year of publication: 2021.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwe4pxtoe2iknys03khl.jpeg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwe4pxtoe2iknys03khl.jpeg\" alt=\"Modern JavaScript for the impatient\"><\/a><\/p>\n\n<p>This book is not for beginners in programming, there is no explanation of the basic things. If you need the basics, then there are plenty of such JavaScript books on the market, just find the right one. It is also not intended for JS programmers who want to learn new, modern standards (there are also enough such books).<\/p>\n\n<p>Kay S. Horstman is a Java advocate and Distinguished Professor of Computer Science at the university. He set himself the goal of writing a book on JavaScript for those who are generally developing in another language (for example, Java, C, C#, or C++), but would like to quickly master JS in its modern form, without historical excursions.<\/p>\n\n<p>What might this be necessary for?<\/p>\n\n<p>The fact is that user interfaces of programs are often hosted on the web, and JS is supported by all browsers. Therefore, even programmers who work in other languages, in principle, periodically need to write something in JavaScript.<\/p>\n\n<p>It's also worth noting that the book is specifically about the JavaScript language, so you won't find information about specific tools and frameworks in it. But it has a separate chapter dedicated to TypeScript.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.oreilly.com\/library\/view\/javascript-the-definitive\/9781491952016\/\" rel=\"noopener noreferrer\">JavaScript: The Definitive Guide<\/a>\n<\/h2>\n\n<p>By David Flanagan. Year of publication: 2021.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglm8i5fy1sksguspt70z.jpeg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglm8i5fy1sksguspt70z.jpeg\" alt=\"JavaScript: The Definitive Guide\"><\/a><\/p>\n\n<p>David Flanagan is a well-known author of books on JavaScript, and also a programmer at Vmware.<\/p>\n\n<p>This book is a thick and detailed reference guide. The author examines the JavaScript language itself, as well as the JS APIs implemented in browsers and Node.<\/p>\n\n<p>The Book with a Rhinoceros is intended for readers who have experience in programming and want to learn JavaScript as well. It will also be of interest to JS developers who want to dive deeper into this language.<\/p>\n\n<p>In 2021, the 7th edition of Flanagan's work was published.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.oreilly.com\/library\/view\/javascript-everywhere\/9781492046974\/\" rel=\"noopener noreferrer\">JavaScript Everywhere<\/a>\n<\/h2>\n\n<p>Authors: Adam D. Scott. Year of publication: 2021. Language: Russian.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuxmywdta1xzcqqwtycm.jpeg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuxmywdta1xzcqqwtycm.jpeg\" alt=\"JavaScript Everywhere\"><\/a><\/p>\n\n<p>Adam D. Scott is a leading web developer at the Consumer Financial Protection Bureau in the United States, creating open web applications. In addition, for many years he was engaged in training and drawing up curricula in technical disciplines. In general, we can say that this is an ideal specialist in teaching web development.<\/p>\n\n<p>While teaching, Scott noticed that many people learn better when they create something. That's why his book \"JavaScript Development\" is a practical guide. It is intended for people who are familiar with HTML, CSS, and JavaScript, but are not yet able to use this knowledge to create real applications.<\/p>\n\n<p>As you read this book, you will understand the compatibility principles of different parts of the program, so you can build great applications.<\/p>\n\n<p>You will learn how to create APIs using Node, Express, MongoDB, and Apollo Server, and get acquainted with React. Then you'll start creating a web application using React, Apollo Client, and CSS-in-JS, as well as Electron-based applications. Mobile development is also in the plan: You'll learn how to use React Native and Expo to develop apps for iOS and Android.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.manning.com\/books\/deep-learning-with-javascript\" rel=\"noopener noreferrer\">Deep Learning with JavaScript<\/a>\n<\/h2>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwliya1mafvtc04tihwd.jpg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwliya1mafvtc04tihwd.jpg\" alt=\"Deep Learning with JavaScript\"><\/a><\/p>\n\n<p>Authors: Francois Chollet, Eric Nielson, Stan Bayleschi, Shengquing Tsei. Year of publication: 2021.<\/p>\n\n<p>TensorFlow.js \u2014 the first full-featured library for creating neural networks in JavaScript. It provides many opportunities in the field of machine learning, and Scholle's book can serve as a guide to these opportunities.<\/p>\n\n<p>As you read this book, you will learn more about the TensorFlow API.Learn how to use js to enter, process, and format data, create and load models, and perform inference, evaluation, and training.<\/p>\n\n<p>The book covers the basic concepts of machine learning in detail. Everything is explained using examples of JS code, using pseudocode and schemas. All the examples are open source, so you can experiment with them.<\/p>\n\n<p>But Scholle doesn't stop at just the basics of ML. The book also includes information on newer topics: text translation, generative models, and reinforcement learning.<\/p>\n\n<p>This book is intended for experienced JavaScript programmers who would like to try their hand at machine learning.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.manning.com\/books\/the-joy-of-javascript\" rel=\"noopener noreferrer\">The Joy of JavaScript<\/a>\n<\/h2>\n\n<p>Author: Luis Atencio. Year of publication: 2021.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpedc5i780zozrd2pxhq1.jpg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpedc5i780zozrd2pxhq1.jpg\" alt=\"The Joy of JavaScript\"><\/a><\/p>\n\n<p>This book is intended for intermediate and advanced programmers, i.e. for those who have already mastered the basics of the language, but want to raise their understanding of its features to a new level. In theory, this should allow them to start getting real pleasure from programming in JavaScript.<\/p>\n\n<p>As you read this book, you will learn what JS can offer a developer on its own, without third-party libraries or frameworks.<\/p>\n\n<p>The author covers the basics of JavaScript only in passing, devoting more time to advanced topics, so this book is not suitable for beginners.<\/p>\n\n<h2>\n  \n  \n  <a href=\"https:\/\/www.oreilly.com\/library\/view\/javascript-cookbook-3rd\/9781492055747\/\" rel=\"noopener noreferrer\">JavaScript Cookbook<\/a>\n<\/h2>\n\n<p>Authors: Adam D. Scott, Matthew MacDonald, Shelley Powers. Year of publication: 2021.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6reros4lxhm40rwqxxn.jpg\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6reros4lxhm40rwqxxn.jpg\" alt=\"JavaScript Cookbook\"><\/a><\/p>\n\n<p>The Recipe Book offers ready-made solutions for common programming tasks. It also explains how to create applications that work in any browser.<\/p>\n\n<p>This book is intended for practicing developers who are looking for solutions to specific problems related to JavaScript. It can be read from cover to cover, absorbing knowledge and getting acquainted with tips on a variety of topics. However, since the problems discussed are divided into categories, the book can also be used as a reference book.<\/p>\n\n<p>In the first part of the book, the authors give recipes for using the JavaScript language itself. The second part is devoted to JS in its natural habitat: in the browser. The third part deals with issues related to Node.js.<\/p>\n\n<h2>\n  \n  \n  Conclusion\n<\/h2>\n\n<p>JavaScript books are a great investment for a web developer. In this article, we have shared with you reviews of some of the newest books. We hope that they will help you find your way around and purchase the most suitable book for you.<\/p>\n\n","category":["javascript","books","webdev","programming"]},{"title":"Common algorithms and data structures in JavaScript: objects and hashing","pubDate":"Sun, 19 Dec 2021 20:09:01 +0000","link":"https:\/\/dev.to\/ra1nbow1\/common-algorithms-and-data-structures-in-javascript-objects-and-hashing-1kdj","guid":"https:\/\/dev.to\/ra1nbow1\/common-algorithms-and-data-structures-in-javascript-objects-and-hashing-1kdj","description":"<p>When we talk about data structures in JavaScript, we can't get past the most important structure of this language \u2013 the object. Let's take a look at what it has under the hood and why hashing algorithms are needed.<\/p>\n\n<h2>\n  \n  \n  Associative array\n<\/h2>\n\n<blockquote>\n<p>JavaScript objects are an example of an associative array. Unlike regular arrays, associative arrays do not have indexes, but rather keys (usually strings). Otherwise, there is almost no difference \u2013 the keys are unique and each corresponds to a certain value. Associative arrays are also called dictionaries or maps (from the English map). They allow you to conveniently represent complex data of various types (for example, user information) and are very popular in JavaScript programming.<\/p>\n<\/blockquote>\n\n<p>In terms of efficiency, associative arrays are superior to other data structures: all basic operations in them are performed in constant time O(1). For example, to add a new element to the middle of a simple array, you will have to reindex it (we talked about this in the first part). The complexity of this operation is O (n). In an associative array, you simply add a new key to which the value is associated.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Hash tables\n<\/h2>\n\n<p>However, associative arrays have their own weakness \u2013 they cannot be stored in the computer's memory as it is, unlike a regular indexed array. For storing associative arrays, a special structure is used \u2013 a hash table (hash map).<\/p>\n\n<p>Associative arrays are in a sense syntactic sugar, a more convenient add-on to the hash table.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy8bgh5yoybaru4f65dk.png\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy8bgh5yoybaru4f65dk.png\" alt=\"Hash table\"><\/a><\/p>\n\n<p><em>Schematic diagram of the hash table operation<\/em><\/p>\n\n\n\n\n<h2>\n  \n  \n  Hashing\n<\/h2>\n\n<p>To turn the key of an associative array into an index of a regular one, you need to perform 2 operations:<\/p>\n\n<ul>\n<li>Find hash (hash the key);<\/li>\n<li>Convert the found hash to the index of the resulting array.<\/li>\n<\/ul>\n\n<p>That is, the final task is to convert the key to a numeric index, but it is usually performed in two steps.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Calculating the hash\n<\/h2>\n\n<p>The hash function receives input data and converts it to a fixed \u2013 length hash string or number. You've probably heard about some of the hash algorithms: CRC32, MD5, and SHA. The key can be represented by any data type that the hash function can handle.<\/p>\n\n<p>Example hash-ID of a commit in git. When you save changes, they are hashed and you get something like <code>0481e0692e2501192d67d7da506c6e70ba41e913<\/code>. This is the hash calculated for your changes.<\/p>\n\n<p>The implementation of a hash function can be very different. For example, you can use the simplest identity function, which takes an input parameter and returns it unchanged:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">hash<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">key<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">key<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>If the keys are strings, you can calculate the sum of the codes of all characters:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">hash<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">string<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">result<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">for <\/span><span class=\"p\">(<\/span><span class=\"kd\">let<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">string<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">result<\/span> <span class=\"o\">+=<\/span> <span class=\"nx\">string<\/span><span class=\"p\">.<\/span><span class=\"nf\">charCodeAt<\/span><span class=\"p\">(<\/span><span class=\"nx\">i<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">result<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>For example, <strong>name<\/strong> the hash value for a key is 417, and the hash value for a key <strong>age<\/strong> is 301.<\/p>\n\n<p>All of these are not very good examples of hash functions, they are usually more complex in real life, but it is important for us to understand the general principle. If you know what data your hash table is going to work with, you can choose a more specific hash function than in the general case.<\/p>\n\n<p><strong><u>Important<\/u><\/strong>: for the same input value, the hash function always returns the same result.<\/p>\n\n<h3>\n  \n  \n  Casting to an index\n<\/h3>\n\n<p>Usually, the size of the resulting array is determined immediately, so the index must be within the specified limits. The hash is usually larger than the index, so it needs to be further converted.<\/p>\n\n<p>To calculate the index, you can use the remainder of dividing the hash by the size of the array:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">index<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">Math<\/span><span class=\"p\">.<\/span><span class=\"nf\">abs<\/span><span class=\"p\">(<\/span><span class=\"nx\">hash<\/span><span class=\"p\">)<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">5<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>It is important to remember that the longer the array is, the more space it takes up in memory.<\/p>\n\n<p>Let's use our hash function and convert an associative array to a regular one:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"c1\">\/\/ associative array<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">user<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">John<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n  <span class=\"na\">age<\/span><span class=\"p\">:<\/span> <span class=\"mi\">23<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"c1\">\/\/ default array, length = 5<\/span>\n<span class=\"p\">[<\/span>\n    <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">age<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"mi\">23<\/span><span class=\"p\">],<\/span>\n    <span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">name<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">John<\/span><span class=\"dl\">'<\/span><span class=\"p\">],<\/span>\n    <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span>\n    <span class=\"kc\">undefined<\/span>\n<span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The key <strong>name<\/strong> corresponds to index 2, and the key <strong>age<\/strong> corresponds to index 1.<\/p>\n\n<p><em>We store not only the values in the resulting array, but also the original keys. Why this is necessary, we will find out very soon.<\/em><\/p>\n\n<p>If we now want to get an array element with a key <strong>name<\/strong>, then we need to hash this key again to find out at what index the associated element is located in the array.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Collisions\n<\/h2>\n\n<p><em>Do you already see the weak point of such transformations?<\/em><\/p>\n\n<blockquote>\n<p>The key in an associative array can be absolutely any string of any length \u2013 the number of options is infinite. And the number of indexes in the array is limited. In other words, there are not enough indexes for all keys, and for some input data, the hash function will return the same result. This is called a collision.<\/p>\n<\/blockquote>\n\n<p>There are two common ways to resolve collisions.<\/p>\n\n<h3>\n  \n  \n  Open addressing\n<\/h3>\n\n<p>Let's assume that we passed the hash function some key of an associative array (<strong>key1<\/strong>) and received from it the 2-index of a regular array that corresponds to this key.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"p\">[<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key1<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value1<\/span><span class=\"p\">],<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span> <span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Then we pass it another key \u2013 <strong>key2<\/strong> \u2013 and again we get <u>2<\/u> \u2013 there was a collision. We can't write new data under the same index, so we just start looking for the first free space in the array. This is called linear probing. The next index after 2-3 \u2013 is free, we write new data to it:<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"p\">[<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key1<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value1<\/span><span class=\"p\">],<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key2<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value2<\/span><span class=\"p\">],<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span> <span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>For the third key <strong>key3<\/strong>, the hash function returns index 3 \u2013 but it is already occupied by the key <strong>key2<\/strong>, so we have to search for free space again.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"p\">[<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span>  <span class=\"p\">[<\/span><span class=\"nx\">key1<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value1<\/span><span class=\"p\">],<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key2<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value2<\/span><span class=\"p\">],<\/span> <span class=\"p\">[<\/span><span class=\"nx\">key3<\/span><span class=\"p\">,<\/span><span class=\"nx\">value3<\/span><span class=\"p\">],<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">,<\/span> <span class=\"kc\">undefined<\/span> <span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The record is clear, but how can you find the desired key in such a hash table, for example, <strong>key3<\/strong>? Similarly, we first run it through the hash function and get <u>3<\/u>. We check the array element at this index and see that this is not the key we are looking for. That's why we store the source key in a hash table, so that we can make sure that the found element is exactly the one we need. We just start moving further through the array, iterating over each element and comparing it with the key we are looking for.<\/p>\n\n<p>The more densely populated the hash table is, the more iterations you need to do to detect a key that is out of place.<\/p>\n\n<h3>\n  \n  \n  Chain method\n<\/h3>\n\n<p>In this approach, values corresponding to a single index are stored as a linked list. each index of the array corresponds not to one element, but to a whole list of elements for which the hash function calculated one index. If a collision occurs, the new element is simply added to the end of the list.<\/p>\n\n<p><a href=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1yqy86tv037niw7vk67.png\" class=\"article-body-image-wrapper\"><img src=\"https:\/\/media.dev.to\/dynamic\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1yqy86tv037niw7vk67.png\" alt=\"Hash table scheme\"><\/a><\/p>\n\n<p>When searching for an element with a specific key in such a hash table, we first calculate its hash, determine the desired array index, and then look through the entire list until we find the desired key.<\/p>\n\n<p>This implementation makes it easy to delete items from the table, because in a linked list, the delete operation takes constant time.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Implementing a hash table in JavaScript\n<\/h2>\n\n<p>The hash table must implement the associative array interface, i.e. provide three main methods:<\/p>\n\n<ul>\n<li>adding a new key-value pair;<\/li>\n<li>search for a value by key;<\/li>\n<li>deleting a pair by key.<\/li>\n<\/ul>\n\n<p>The smaller the hash table size (array length), the more frequent collisions will occur. We'll take a small number, 32, as an example. In practice, prime numbers (which are divisible only by one and by themselves) are often used for the size of a hash table. It is assumed that this results in fewer collisions.<\/p>\n\n<p>To resolve collisions, we will use the chain method. To do this, we need the linked list class <strong>LinkedList<\/strong>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">hashTableSize<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">32<\/span><span class=\"p\">;<\/span>\n\n<span class=\"kd\">class<\/span> <span class=\"nc\">HashTable<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nf\">constructor<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">Array<\/span><span class=\"p\">(<\/span><span class=\"nx\">hashTableSize<\/span><span class=\"p\">).<\/span><span class=\"nf\">fill<\/span><span class=\"p\">(<\/span><span class=\"kc\">null<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nf\">hash<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">hash<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">Array<\/span><span class=\"p\">.<\/span><span class=\"k\">from<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">).<\/span><span class=\"nf\">reduce<\/span><span class=\"p\">((<\/span><span class=\"nx\">sum<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">sum<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">key<\/span><span class=\"p\">.<\/span><span class=\"nf\">charCodeAt<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">},<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">hash<\/span> <span class=\"o\">%<\/span> <span class=\"nx\">hashTableSize<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nf\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ calculating the hash for the key<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">index<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">hash<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n\n    <span class=\"c1\">\/\/ create if there is no list for this hash yet<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span><span class=\"p\">[<\/span><span class=\"nx\">index<\/span><span class=\"p\">])<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span><span class=\"p\">[<\/span><span class=\"nx\">index<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">LinkedList<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kd\">let<\/span> <span class=\"nx\">list<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span><span class=\"p\">[<\/span><span class=\"nx\">index<\/span><span class=\"p\">];<\/span>\n    <span class=\"c1\">\/\/ check if the key was added earlier<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">node<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">list<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">((<\/span><span class=\"nx\">nodeValue<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">nodeValue<\/span><span class=\"p\">.<\/span><span class=\"nx\">key<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">key<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">});<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">value<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ updating the value for the key<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">list<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">({<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span> <span class=\"p\">});<\/span> <span class=\"c1\">\/\/ adding a new item to the end of the list<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ calculating the hash for the key<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">index<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">hash<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n    <span class=\"c1\">\/\/ we find the corresponding list in the array<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">list<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span><span class=\"p\">[<\/span><span class=\"nx\">index<\/span><span class=\"p\">];<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">list<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"c1\">\/\/ we are looking for an item with the desired key in the list<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">node<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">list<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">((<\/span><span class=\"nx\">nodeValue<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">nodeValue<\/span><span class=\"p\">.<\/span><span class=\"nx\">key<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">key<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">});<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span> <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">return<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">delete<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">index<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nf\">hash<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">list<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">buckets<\/span><span class=\"p\">[<\/span><span class=\"nx\">index<\/span><span class=\"p\">];<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">list<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"kd\">let<\/span> <span class=\"nx\">node<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">list<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">((<\/span><span class=\"nx\">nodeValue<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">nodeValue<\/span><span class=\"p\">.<\/span><span class=\"nx\">key<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">key<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">node<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"nx\">list<\/span><span class=\"p\">.<\/span><span class=\"k\">delete<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n\n<h2>\n  \n  \n  Efficiency of basic operations in the hash table\n<\/h2>\n\n<p>The main operations in a hash table consist of two stages::<\/p>\n\n<ul>\n<li>calculating the hash for a key and checking the element corresponding to this hash in the resulting array.<\/li>\n<li>iterate through other elements if you didn't find the right one right away.<\/li>\n<\/ul>\n\n<p>The first stage always takes constant time, the second \u2013 linear, that is, it depends on the number of elements that need to be sorted.<\/p>\n\n<p>The effectiveness of a hash table depends on three main factors::<\/p>\n\n<ul>\n<li>Hash function that calculates indexes for keys. Ideally, it should distribute indexes evenly across the array;<\/li>\n<li>The size of the table itself \u2013 the larger it is, the fewer collisions there are;<\/li>\n<li>Collision resolution method. For example, the chaining method reduces the operation of adding a new element to constant time.<\/li>\n<\/ul>\n\n<p>In the end, the fewer collisions, the more efficient the table works, since you don't need to iterate through many elements if the search was not found immediately by hash. In general, the hash table is more efficient than other data structures.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Using hash tables\n<\/h2>\n\n<blockquote>\n<p>Hash tables are widely used in programming, for example, for authorization mechanisms, indexing large amounts of information (databases), caching, or searching. Another common case is the implementation of unordered sets, which we will discuss in the next part of the cycle.<\/p>\n<\/blockquote>\n\n<p>In JavaScript, hash tables in their pure form are rarely used. Usually, all their work is successfully performed by ordinary objects (associative arrays) or more complex <strong>Maps<\/strong>. At the same time, at a lower level (program interpretation) hash tables are used to represent objects.<\/p>\n\n<p>Objects and hash tables are often used as auxiliary structures when optimizing various actions. For example, to count the number of occurrences of different characters in a string.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">function<\/span> <span class=\"nf\">countSymbols<\/span><span class=\"p\">(<\/span><span class=\"nx\">string<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">hash<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{};<\/span>\n    <span class=\"p\">[...<\/span><span class=\"nx\">string<\/span><span class=\"p\">].<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">(<\/span><span class=\"nx\">s<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">let<\/span> <span class=\"nx\">symbol<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">s<\/span><span class=\"p\">.<\/span><span class=\"nf\">toLowerCase<\/span><span class=\"p\">();<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"p\">(<\/span><span class=\"nx\">symbol<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">hash<\/span><span class=\"p\">))<\/span> <span class=\"nx\">hash<\/span><span class=\"p\">[<\/span><span class=\"nx\">symbol<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"nx\">hash<\/span><span class=\"p\">[<\/span><span class=\"nx\">symbol<\/span><span class=\"p\">]<\/span><span class=\"o\">++<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">});<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">hash<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nf\">countSymbols<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">Hello, world!<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n<span class=\"cm\">\/*\n{ \" \": 1, \"!\": 1, \",\": 1, d: 1, e: 1, h: 1, l: 3, o: 2, r: 1, w: 1 }\n*\/<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n\n\n\n<h2>\n  \n  \n  Hashing, encoding, and encryption\n<\/h2>\n\n<blockquote>\n<p>Hashing is an algorithm that works only in one direction. It is impossible to get the original value from the hash, and there is no practical need for this, because the main task of hashing is to distinguish input data, not to save it.<\/p>\n<\/blockquote>\n\n<p>In some cases, we need a two-way transformation. For example, you want to leave a secret message to a friend that no one else can read. This is where encryption algorithms come to the rescue.<\/p>\n\n<blockquote>\n<p>You convert the source text to some other sequence of characters using a cipher. Such a sequence is either completely unreadable (just a set of letters), or it has a completely different meaning. If someone intercepts this email, they simply won't understand what you were trying to say. Your friend knows that the message is encrypted and knows how to decrypt it. Thus, the main purpose of encryption is to hide information from unauthorized persons. To do this, use a secret key or even two keys \u2013 one for encryption, the second for decryption.<\/p>\n<\/blockquote>\n\n<p>In addition to encryption, there is also encoding. It is close to encryption in essence, but different in purpose. Encoding is used to simplify the transmission of information, for example, over telecommunication lines. Your message is converted to a sequence of bits, delivered to the recipient over the wire, and restored again at the other end. No keys are used in this case. Such codes not only solve the problem of communication, but also often try to deal with possible interference during transmission, that is, they have the ability to repair damage. One of the most famous codes is Morse code.<\/p>\n\n\n\n\n<h2>\n  \n  \n  Conclusion\n<\/h2>\n\n<p>While dealing with hash tables, we once again made sure that almost everything in programming is done through ... arrays. So associative objects under the hood also use them, calculating the index for each key using hash functions.<\/p>\n\n","category":["javascript","programming","security","algorithms"]}]}}