Sirwan Afifi

A Senior Software Engineer who has experience developing Web Applications in high-tech companies in the UK. Passionate about the latest technologies, including: Node.js, Deno, Next.js, React, TypeScript, and ASP.NET Core. I love exploring new technologies and experimenting with them.

Latest Articles

\n\n\n```","filePath":"src/content/blog/en/2019-05-31-Razor-Pages-Highlight-Current-Link.md","digest":"0dfb346cfd1851b5","rendered":{"html":"

Let’s say you have several pages in your Razor Pages application. Now you want to make the menu items active depending on the page you are currently on:

\n\"Active\n

The solution is pretty simple; all you need to do is checking the request path in _Layout file. To access the Request object, you need to inject IHttpContextAccessor in the layout file. Before injecting this interface into our view we must register it in ConfigureServices method in Startup class:

\n
public void ConfigureServices(IServiceCollection services)\n{\n    // ...\n    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();\n}
\n

Note: If you are using ASP.NET Core 2.1+ you can use AddHttpContextAccessor helper extension method to correctly register the IHttpContextAccessor with the correct lifetime (singleton):

\n
services.AddHttpContextAccessor();
\n

Now we should be able to access current HttpContext inside our views:

\n
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor Accessor\n<html>\n<head>\n    <title>Layout</title>\n    <link rel=\"stylesheet\" href=\"/css/shared.css\" />\n    @RenderSection(\"styles\", false)\n</head>\n<body>\n    <header class=\"header-shadow\">\n        <div class=\"container is-fluid header\">\n            <nav class=\"navbar\">\n                <div class=\"navbar-menu navbar-end\" id=\"mainNavMenu\">\n                    <a class=\"navbar-item @(Accessor.HttpContext.Request.Path.Value == \"/\" ? \"nav-item-selected\" : \"\" )\" href=\"/\">Home</a>\n                    <a class=\"navbar-item @(Accessor.HttpContext.Request.Path.Value == \"/Services\" ? \"nav-item-selected\" : \"\" )\" href=\"/Services\">Services</a>\n                    <a class=\"navbar-item @(Accessor.HttpContext.Request.Path.Value == \"/About\" ? \"nav-item-selected\" : \"\" )\" href=\"/About\">About Us</a>\n                    <a class=\"navbar-item @(Accessor.HttpContext.Request.Path.Value == \"/Contact\" ? \"nav-item-selected\" : \"\" )\" href=\"/Contact\">Contact</a>\n                </div>\n            </nav>\n        </div>\n    </header>\n\n    @RenderBody()\n\n</body>\n</html>\n
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Highlighting Current Link in Razor Pages","date":"2019-05-31T23:46:37.121Z","template":"post","draft":false,"slug":"Razor-Pages-Highlight-Current-Link/","tags":["Razor","ASP.NET Core"],"category":"Programming","description":"Let's say you have several pages in your Razor Pages application. Now you want to make the menu items active depending on the page you are currently on...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"Razor-Pages-Highlight-Current-Link/"},{"id":"en/2018-10-27-React-Hooks.md","data":{"title":"React Hooks","date":"2018-10-27T23:46:37.121Z","description":"Hooks are a new feature that is coming up in React v16.7.0-alpha, it's a really great feature, I am so excited about this new feature. The goal is to use all functionalities you can ...","template":"post","draft":false,"tags":["ReactJS","TypeScript","JavaScript"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Hooks are a new feature that is coming up in React v16.7.0-alpha, it's a really great feature, I am so excited about this new feature. The goal is to use all functionalities you can do in class components in functional style components, We heavily use functional components in our project so in order to use things like State we have two options: re-writing our component using class components or simply use a package called `react-powerplug`:\n\n```typescript\nimport * as React from \"react\";\nimport { State } from \"react-powerplug\";\n\nconst Example = () => {\n return (\n \n {({ state, setState }) => (\n
\n

You clicked {state.count} times

\n \n
\n )}\n \n );\n};\n\nexport { Example };\n```\n\nIt is great, but we don't need to have this anymore because one of the features provided by Hooks in the new version of React is ability to have state inside a functional component. Here's the same example using React Hooks:\n\n```typescript\nimport { useState } from \"react\";\nimport * as React from \"react\";\n\nexport interface ReactHookProps {}\n\nconst ReactHook = (props: ReactHookProps) => {\n const [count, setCount] = useState(0);\n\n return (\n
\n

Hello From ReactHook Component

\n

You clicked {count} times

\n \n
\n );\n};\n\nexport { ReactHook };\n```\n\nAs you can see, by calling `useState` and passing a default value, it gives you two properties; one for `get` and the other for `set`. The interesting point about `useState` is that we can have multiple states inside the component:\n\n```typescript\nconst [person, setPerson] = useState({\n firstName: \"Sirwan\",\n lastName: \"Afifi\",\n age: 29,\n});\n```\n\nWorking with state is just one of `Hooks` functionalities, I will try to blog about the other features too.\n\nYou can grab the working sample project from [GitHub](https://github.com/SirwanAfifi/react-hooks.git).\n\nHappy coding :)","filePath":"src/content/blog/en/2018-10-27-React-Hooks.md","assetImports":["./covers/cover.png"],"digest":"0e5d353309d71913","rendered":{"html":"

Hooks are a new feature that is coming up in React v16.7.0-alpha, it’s a really great feature, I am so excited about this new feature. The goal is to use all functionalities you can do in class components in functional style components, We heavily use functional components in our project so in order to use things like State we have two options: re-writing our component using class components or simply use a package called react-powerplug:

\n
import * as React from \"react\";\nimport { State } from \"react-powerplug\";\n\nconst Example = () => {\n  return (\n    <State\n      initial={{\n        count: 0,\n      }}\n    >\n      {({ state, setState }) => (\n        <div>\n          <p>You clicked {state.count} times</p>\n          <button onClick={() => setState({ count: state.count + 1 })}>\n            Click me\n          </button>\n        </div>\n      )}\n    </State>\n  );\n};\n\nexport { Example };
\n

It is great, but we don’t need to have this anymore because one of the features provided by Hooks in the new version of React is ability to have state inside a functional component. Here’s the same example using React Hooks:

\n
import { useState } from \"react\";\nimport * as React from \"react\";\n\nexport interface ReactHookProps {}\n\nconst ReactHook = (props: ReactHookProps) => {\n  const [count, setCount] = useState(0);\n\n  return (\n    <div>\n      <h1>Hello From ReactHook Component</h1>\n      <p>You clicked {count} times</p>\n      <button onClick={() => setCount(count + 1)}>Click me</button>\n    </div>\n  );\n};\n\nexport { ReactHook };
\n

As you can see, by calling useState and passing a default value, it gives you two properties; one for get and the other for set. The interesting point about useState is that we can have multiple states inside the component:

\n
const [person, setPerson] = useState({\n  firstName: \"Sirwan\",\n  lastName: \"Afifi\",\n  age: 29,\n});
\n

Working with state is just one of Hooks functionalities, I will try to blog about the other features too.

\n

You can grab the working sample project from GitHub.

\n

Happy coding :)

","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"React Hooks","date":"2018-10-27T23:46:37.121Z","template":"post","draft":false,"slug":"React-Hooks/","tags":["ReactJS","TypeScript","JavaScript"],"category":"Programming","description":"Hooks are a new feature that is coming up in React v16.7.0-alpha, it's a really great feature, I am so excited about this new feature. The goal is to use all functionalities you can ...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"React-Hooks/"},{"id":"en/2019-07-08-Programming-challenges-morse-code.md","data":{"title":"Morse code","date":"2019-07-08T23:46:37.121Z","description":"Morse Code is a set of dots and dashes (short mark, dot or 'dit' (·) and longer mark, dash or 'dah' (-)). Basically, it's a character encoding scheme for transmitting cryptographic messages which used in telecommunication. Think of it as the early version of texting. ...","template":"post","draft":false,"tags":["Algorithm","React","Morse"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"\"Morse\n\nMorse Code is a set of dots and dashes (short mark, dot or 'dit' (·) and longer mark, dash or 'dah' (-)). Basically, it's a character encoding scheme for transmitting cryptographic messages which used in telecommunication. Think of it as the early version of texting. The system is named after the American artist Samuel Finley Breese Morse who co-developed an electrical telegraph system at the beginning of 1836. In fact it was heavily used for (secret) transmissions during WWI and WWII. Different combination of dots and dashes will produce different letters it also means that different combination of letters will be eventually your encoded messages.\n\n\"Morse\n\nI thought it might be a good idea to write my name in Morse code to see how it looks like. Since I am a lazy developer, so I ended up writing a React application to do the job for me:\n\n\"Morse\n\nHere's the implementation in JavaScript:\n\n```js\nconst language = {\n alphabets: {\n A: \"•−\",\n B: \"−•••\",\n C: \"−•−•\",\n D: \"−••\",\n E: \"•\",\n F: \"••−•\",\n G: \"−−•\",\n H: \"••••\",\n I: \"••\",\n J: \"•−−−\",\n K: \"−•−\",\n M: \"−−\",\n N: \"−•\",\n L: \"•−••\",\n N: \"−•\",\n O: \"−−−\",\n P: \"•−−•\",\n Q: \"−−•−\",\n R: \"•−•\",\n S: \"•••\",\n T: \"−\",\n U: \"••−\",\n V: \"••−\",\n W: \"•−−\",\n X: \"−••−\",\n Y: \"−•−−\",\n Z: \"−−••\",\n },\n numeral: {\n 1: \"•−−−−\",\n 2: \"••−−−\",\n 3: \"••−−\",\n 4: \"•••−\",\n 5: \"•••••\",\n 6: \"−••••\",\n 7: \"−−•••\",\n 8: \"−−−••\",\n 9: \"−−−−•\",\n 0: \"−−−−−\",\n },\n punctuations: {\n \"•\": \"•−•−•−\",\n \",\": \"−−••−−\",\n \"?\": \"••−−••\",\n \":\": \"−−−•••\",\n \";\": \"−•−•−•\",\n \"−\": \"−••••−\",\n \"/\": \"−••−•\",\n '\"': \"•−••−•\",\n \"'\": \"•−−−−•\",\n \"(\": \"−•−−•\",\n \")\": \"−•−−•−\",\n \"=\": \"−•••−\",\n \"+\": \"•−•−•\",\n $: \"••−••−\",\n q: \"•−•−••\",\n _: \"••−−•−\",\n },\n};\n\nconst translateToMorseCode = (input) => {\n const inputArray = [...input];\n const morseCode = inputArray.map((i) => {\n const code =\n language.alphabets[i.toUpperCase()] ||\n language.numeral[i] ||\n language.punctuations[i];\n return code || \"\";\n });\n return morseCode.join(\" \");\n};\n\nconst translateToEnglish = (input) => {\n const inputArray = input.split(\" \");\n const engWord = inputArray.map((i) => {\n const value =\n Object.keys(language.alphabets).filter((key) => {\n return language.alphabets[key] === i;\n })[0] ||\n Object.keys(language.punctuations).filter((key) => {\n return language.punctuations[key] === i;\n })[0] ||\n Object.keys(language.numeral).filter((key) => {\n return language.numeral[key] === i;\n })[0];\n return value ? value.toLocaleLowerCase() : \"\";\n });\n return engWord.join(\" \");\n};\n```\n\nSince the original idea of Morse Code was to signal the message in a form perceptible to the human senses, such as sound waves or visible light, so I have added the ability to play a sound while coding the message:\n\n```js\nasync display() {\n this.setState({ loading: true });\n this.setState({ output: \"\" });\n for (let i of [...translateToMorseCode(this.state.input)]) {\n await sleep(200);\n if (i === \"•\") {\n playSound();\n }\n else if (i === \"−\") {\n playSound();\n playSound();\n }\n this.setState({ output: this.state.output + \"\" + i });\n }\n this.setState({ loading: false });\n}\n```\n\nYou can grab the working sample project from [GitHub](https://github.com/SirwanAfifi/morse).","filePath":"src/content/blog/en/2019-07-08-Programming-challenges-morse-code.md","assetImports":["./covers/cover.png"],"digest":"9e296b996b27a59d","rendered":{"html":"\"Morse\n

Morse Code is a set of dots and dashes (short mark, dot or ‘dit’ (·) and longer mark, dash or ‘dah’ (-)). Basically, it’s a character encoding scheme for transmitting cryptographic messages which used in telecommunication. Think of it as the early version of texting. The system is named after the American artist Samuel Finley Breese Morse who co-developed an electrical telegraph system at the beginning of 1836. In fact it was heavily used for (secret) transmissions during WWI and WWII. Different combination of dots and dashes will produce different letters it also means that different combination of letters will be eventually your encoded messages.

\n\"Morse\n

I thought it might be a good idea to write my name in Morse code to see how it looks like. Since I am a lazy developer, so I ended up writing a React application to do the job for me:

\n\"Morse\n

Here’s the implementation in JavaScript:

\n
const language = {\n  alphabets: {\n    A: \"•−\",\n    B: \"−•••\",\n    C: \"−•−•\",\n    D: \"−••\",\n    E: \"•\",\n    F: \"••−•\",\n    G: \"−−•\",\n    H: \"••••\",\n    I: \"••\",\n    J: \"•−−−\",\n    K: \"−•−\",\n    M: \"−−\",\n    N: \"−•\",\n    L: \"•−••\",\n    N: \"−•\",\n    O: \"−−−\",\n    P: \"•−−•\",\n    Q: \"−−•−\",\n    R: \"•−•\",\n    S: \"•••\",\n    T: \"−\",\n    U: \"••−\",\n    V: \"••−\",\n    W: \"•−−\",\n    X: \"−••−\",\n    Y: \"−•−−\",\n    Z: \"−−••\",\n  },\n  numeral: {\n    1: \"•−−−−\",\n    2: \"••−−−\",\n    3: \"••−−\",\n    4: \"•••−\",\n    5: \"•••••\",\n    6: \"−••••\",\n    7: \"−−•••\",\n    8: \"−−−••\",\n    9: \"−−−−•\",\n    0: \"−−−−−\",\n  },\n  punctuations: {\n    \"•\": \"•−•−•−\",\n    \",\": \"−−••−−\",\n    \"?\": \"••−−••\",\n    \":\": \"−−−•••\",\n    \";\": \"−•−•−•\",\n    \"−\": \"−••••−\",\n    \"/\": \"−••−•\",\n    '\"': \"•−••−•\",\n    \"'\": \"•−−−−•\",\n    \"(\": \"−•−−•\",\n    \")\": \"−•−−•−\",\n    \"=\": \"−•••−\",\n    \"+\": \"•−•−•\",\n    $: \"••−••−\",\n    q: \"•−•−••\",\n    _: \"••−−•−\",\n  },\n};\n\nconst translateToMorseCode = (input) => {\n  const inputArray = [...input];\n  const morseCode = inputArray.map((i) => {\n    const code =\n      language.alphabets[i.toUpperCase()] ||\n      language.numeral[i] ||\n      language.punctuations[i];\n    return code || \"\";\n  });\n  return morseCode.join(\" \");\n};\n\nconst translateToEnglish = (input) => {\n  const inputArray = input.split(\" \");\n  const engWord = inputArray.map((i) => {\n    const value =\n      Object.keys(language.alphabets).filter((key) => {\n        return language.alphabets[key] === i;\n      })[0] ||\n      Object.keys(language.punctuations).filter((key) => {\n        return language.punctuations[key] === i;\n      })[0] ||\n      Object.keys(language.numeral).filter((key) => {\n        return language.numeral[key] === i;\n      })[0];\n    return value ? value.toLocaleLowerCase() : \"\";\n  });\n  return engWord.join(\" \");\n};
\n

Since the original idea of Morse Code was to signal the message in a form perceptible to the human senses, such as sound waves or visible light, so I have added the ability to play a sound while coding the message:

\n
async display() {\n    this.setState({ loading: true });\n    this.setState({ output: \"\" });\n    for (let i of [...translateToMorseCode(this.state.input)]) {\n        await sleep(200);\n        if (i === \"•\") {\n            playSound();\n        }\n        else if (i === \"−\") {\n            playSound();\n            playSound();\n        }\n        this.setState({ output: this.state.output + \"\" + i });\n    }\n    this.setState({ loading: false });\n}
\n

You can grab the working sample project from GitHub.

","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Morse code","date":"2019-07-08T23:46:37.121Z","template":"post","draft":false,"slug":"Programming-challenges-morse-code/","tags":["Algorithm","React","Morse"],"category":"Programming","description":"Morse Code is a set of dots and dashes (short mark, dot or 'dit' (·) and longer mark, dash or 'dah' (-)). Basically, it's a character encoding scheme for transmitting cryptographic messages which used in telecommunication. Think of it as the early version of texting. ...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Programming-challenges-morse-code/"},{"id":"en/2019-07-22-Migrating-To-Gatsby.md","data":{"title":"Migrating To Gatsby","date":"2019-07-22T23:46:37.121Z","description":"I've been playing around with Gatsby, and so far I'm quite happy. It's basically a framework based on React and GraphQL that makes it easy to create both website and web applications.","template":"post","draft":false,"tags":["Gatsby","React","GraphQL"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Jekyll got me into blogging mostly because of its markdown support. When I first saw it, it was clear to me I had to have it. I'd say it was(still is) a fast possible way for blogging and I liked it. Also, the additional bonus was to host the blog using GitHub pages. Jekyll is excellent; It gets you started quickly without having to worry about how to set up things. Recently I decided to use JavaScript-based solutions. Gatsby has been the 1st item in my list. I've been playing around with it, and so far I'm quite happy. It's basically a framework based on React and GraphQL that makes it easy to create both website and web applications. It's also a static website generator. The cool thing about Gatsby is that we can also use it for building complex web apps with data storage, authentication and more. These abstractions allow us to connect any data source to our application.\n\n\"gatsby\"\n\n## Why Gatsby?\n\n- It's super fast\n- It's super easy to work with\n- It has so many features baked right in\n- We can create a web project in a matter of minutes without needing to install/customise build tools\n- It comes with everything we need to get started right away\n\nPublishing a blog post can be done in a few lines now:\n\n```js\ngit add . && git commit -m \"new blog\"\nnpm run deploy:github\n```\n\nI feel like everything feels more under control now:\n\n\"gatsby\"","filePath":"src/content/blog/en/2019-07-22-Migrating-To-Gatsby.md","assetImports":["./covers/cover.png"],"digest":"86a85a89b13b522e","rendered":{"html":"

Jekyll got me into blogging mostly because of its markdown support. When I first saw it, it was clear to me I had to have it. I’d say it was(still is) a fast possible way for blogging and I liked it. Also, the additional bonus was to host the blog using GitHub pages. Jekyll is excellent; It gets you started quickly without having to worry about how to set up things. Recently I decided to use JavaScript-based solutions. Gatsby has been the 1st item in my list. I’ve been playing around with it, and so far I’m quite happy. It’s basically a framework based on React and GraphQL that makes it easy to create both website and web applications. It’s also a static website generator. The cool thing about Gatsby is that we can also use it for building complex web apps with data storage, authentication and more. These abstractions allow us to connect any data source to our application.

\n\"gatsby\"\n

Why Gatsby?

\n\n

Publishing a blog post can be done in a few lines now:

\n
git add . && git commit -m \"new blog\"\nnpm run deploy:github
\n

I feel like everything feels more under control now:

\n\"gatsby\"","metadata":{"headings":[{"depth":2,"slug":"why-gatsby","text":"Why Gatsby?"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Migrating To Gatsby","date":"2019-07-22T23:46:37.121Z","template":"post","draft":false,"slug":"Migrating-To-Gatsby/","tags":["Gatsby","React","GraphQL"],"category":"Programming","description":"I've been playing around with Gatsby, and so far I'm quite happy. It's basically a framework based on React and GraphQL that makes it easy to create both website and web applications.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Migrating-To-Gatsby/"},{"id":"en/2019-09-22-Higher-Order-Components.md","data":{"title":"Higher-Order Components","date":"2019-09-22T23:46:37.121Z","description":"Higher-Order Components are a great way to share common functionality between components without repeating code.","template":"post","draft":false,"tags":["React"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Before we get started, we need to understand what a higher-order function is. In JavaScript functions are first-class citizens because they are treated like any other variables:\n\n- They can be created using literals:\n\n```js\nfunction myFunction() {\n // function body\n}\n```\n\n- They can be assigned to other types:\n\n```js\nvar myFunction = function () {\n // function body\n};\nmyArray.push(function () {\n // function body\n});\nmyObj.data = function () {\n // function body\n};\n```\n\n- A function can be passed to another function as an argument:\n\n```js\nfunction invoke(myFunction) {\n myFunction();\n}\n\ninvoke(function () {\n // function body\n});\n```\n\n- A function can return another function:\n\n```js\nfunction myFunction() {\n return function () {\n // function body, inside this scope we can also have access to outter scope\n };\n}\n```\n\n- We can add new properties to a function:\n\n```js\nvar myFunction = function () {\n // function body\n};\nmyFunction.name = \"Function name\";\n```\n\n## Higher-Order Component(Function)\n\nNow talking about Higher-Order function makes more sense. A higher-order function is basically a function that can take another function as an argument, or returns a function as a result. In React it's pretty much the same concept; It takes a component as an argument and returns a component:\n\n```js\nfunction MyComponent(Component) {\n return class extends Component {\n constructor(props) {\n super(props);\n }\n\n render() {\n return ;\n }\n };\n}\n```\n\nIt's great becuase we can wrap a component with another component; this means that we can add extra functionalities to a component so it can be usfuel to share common functionality between components without repeating code. They are often used for `cross-cutting` concerns. An example of it could be private routes inside a React application:\n\n```js\nimport React from \"react\";\nimport { Route, Redirect } from \"react-router-dom\";\nexport const PrivateRoute = ({ component: Component, ...rest }) => (\n \n isUserAuthenticated() ? (\n \n ) : (\n \n )\n }\n />\n);\n```\n\nHere, the `PrivateRoute` is itself a function that is used to enhance another component. The way it enhance is to wrap the incoming component with `Route` component.","filePath":"src/content/blog/en/2019-09-22-Higher-Order-Components.md","assetImports":["./covers/cover.png"],"digest":"c4de5335a5416450","rendered":{"html":"

Before we get started, we need to understand what a higher-order function is. In JavaScript functions are first-class citizens because they are treated like any other variables:

\n
    \n
  • They can be created using literals:
  • \n
\n
function myFunction() {\n  // function body\n}
\n
    \n
  • They can be assigned to other types:
  • \n
\n
var myFunction = function () {\n  // function body\n};\nmyArray.push(function () {\n  // function body\n});\nmyObj.data = function () {\n  // function body\n};
\n
    \n
  • A function can be passed to another function as an argument:
  • \n
\n
function invoke(myFunction) {\n  myFunction();\n}\n\ninvoke(function () {\n  // function body\n});
\n
    \n
  • A function can return another function:
  • \n
\n
function myFunction() {\n  return function () {\n    // function body, inside this scope we can also have access to outter scope\n  };\n}
\n
    \n
  • We can add new properties to a function:
  • \n
\n
var myFunction = function () {\n  // function body\n};\nmyFunction.name = \"Function name\";
\n

Higher-Order Component(Function)

\n

Now talking about Higher-Order function makes more sense. A higher-order function is basically a function that can take another function as an argument, or returns a function as a result. In React it’s pretty much the same concept; It takes a component as an argument and returns a component:

\n
function MyComponent(Component) {\n  return class extends Component {\n    constructor(props) {\n      super(props);\n    }\n\n    render() {\n      return <Component {...this.props} />;\n    }\n  };\n}
\n

It’s great becuase we can wrap a component with another component; this means that we can add extra functionalities to a component so it can be usfuel to share common functionality between components without repeating code. They are often used for cross-cutting concerns. An example of it could be private routes inside a React application:

\n
import React from \"react\";\nimport { Route, Redirect } from \"react-router-dom\";\nexport const PrivateRoute = ({ component: Component, ...rest }) => (\n  <Route\n    {...rest}\n    render={(props) =>\n      isUserAuthenticated() ? (\n        <Component {...props} />\n      ) : (\n        <Redirect\n          to={{\n            pathname: \"/login\",\n            state: { from: props.location },\n          }}\n        />\n      )\n    }\n  />\n);
\n

Here, the PrivateRoute is itself a function that is used to enhance another component. The way it enhance is to wrap the incoming component with Route component.

","metadata":{"headings":[{"depth":2,"slug":"higher-order-componentfunction","text":"Higher-Order Component(Function)"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Higher-Order Components","date":"2019-09-22T23:46:37.121Z","template":"post","draft":false,"slug":"Higher-Order-Components/","tags":["React"],"category":"Programming","description":"Higher-Order Components are a great way to share common functionality between components without repeating code.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Higher-Order-Components/"},{"id":"en/2019-10-02-Testing-React-Components.md","data":{"title":"Testing React Components","date":"2019-10-02T23:46:37.121Z","description":"Testing React components is a crucial part of the development process. It helps us to make sure that our components are working as expected.","template":"post","draft":false,"tags":["React"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"`create-react-app` comes with a built-in test runner called `Jest` which is basically a tool for executing unite tests and also reporting the result. To run the test files in projects, all we need to do is type in `npm run test` command. This command searches for all test files in the project and executes them one after another. Once the tests have been run, it enters into watch mode, which means that whenever we change the test files in goes and re-run them.\n\nThere are two approaches that we can use for testing a component:\n\n- Shallow rendering\n- Full rendering\n\n# Shallow rendering\n\nShallow rendering allows us to render a component without rendering its children. It means that it isolates the component from its children. This type of rendering makes more sense when testing a component's functionality. For example, let's say we have a blog application and want to check if the `App` component contains a header:\n\n```js\nimport React from \"react\";\nimport Adapter from \"enzyme-adapter-react-16\";\nimport Enzyme, { shallow } from \"enzyme\";\nimport App from \"./App\";\nimport { Header } from \"./components/Header\";\n\nEnzyme.configure({ adapter: new Adapter() });\n\nit(\"renders app component\", () => {\n const wrapper = shallow();\n const header =
;\n expect(wrapper.contains(header)).toEqual(true);\n});\n```\n\nSince the test is using shallow rendering, the child components are not used to render it means that only the `App` component's state and props are used for when rendering the content and its children are not rendered:\n\n```js\n\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
\n \n
\n
\n
\n
\n```\n\n# Full rendering\n\nFull rendering means that the `App` component children are fully rendered:\n\n```js\nit(\"renders app component\", () => {\n const wrapper = mount();\n const header =
;\n expect(wrapper.contains(header)).toEqual(true);\n});\n```\n\nWhich produeces the following output.\n\n```html\n\n
\n
\n
\n \n
\n
\n
\n
\n
\n
\n \n

Latest posts

\n
\n \n \n \n
\n
\n \n
\n

Post1

\n
\n

Hello

\n
\n
\n
\n \n
\n

Post2

\n
\n

Hello

\n
\n
\n
\n \n
\n

Post3

\n
\n

Hello

\n
\n
\n
\n \n
\n

Post4

\n
\n

Hello

\n
\n
\n
\n
\n
\n
\n
\n \n

Authors

\n \n
\n
\n
\n
\n
\n```","filePath":"src/content/blog/en/2019-10-02-Testing-React-Components.md","assetImports":["./covers/cover.png"],"digest":"69f065e71cd3246d","rendered":{"html":"

create-react-app comes with a built-in test runner called Jest which is basically a tool for executing unite tests and also reporting the result. To run the test files in projects, all we need to do is type in npm run test command. This command searches for all test files in the project and executes them one after another. Once the tests have been run, it enters into watch mode, which means that whenever we change the test files in goes and re-run them.

\n

There are two approaches that we can use for testing a component:

\n
    \n
  • Shallow rendering
  • \n
  • Full rendering
  • \n
\n

Shallow rendering

\n

Shallow rendering allows us to render a component without rendering its children. It means that it isolates the component from its children. This type of rendering makes more sense when testing a component’s functionality. For example, let’s say we have a blog application and want to check if the App component contains a header:

\n
import React from \"react\";\nimport Adapter from \"enzyme-adapter-react-16\";\nimport Enzyme, { shallow } from \"enzyme\";\nimport App from \"./App\";\nimport { Header } from \"./components/Header\";\n\nEnzyme.configure({ adapter: new Adapter() });\n\nit(\"renders app component\", () => {\n  const wrapper = shallow(<App />);\n  const header = <Header />;\n  expect(wrapper.contains(header)).toEqual(true);\n});
\n

Since the test is using shallow rendering, the child components are not used to render it means that only the App component’s state and props are used for when rendering the content and its children are not rendered:

\n
<Fragment>\n  <div className=\"columns\">\n    <div className=\"column\">\n      <Header />\n    </div>\n  </div>\n  <div className=\"container\">\n    <div className=\"columns\">\n      <div className=\"column is-8\">\n        <List />\n      </div>\n      <div className=\"column is-4\">\n        <AuthorList />\n      </div>\n    </div>\n  </div>\n</Fragment>
\n

Full rendering

\n

Full rendering means that the App component children are fully rendered:

\n
it(\"renders app component\", () => {\n  const wrapper = mount(<App />);\n  const header = <Header />;\n  expect(wrapper.contains(header)).toEqual(true);\n});
\n

Which produeces the following output.

\n
<App>\n  <div className=\"columns\">\n    <div className=\"column\">\n      <header>\n        <nav className=\"navbar is-primary\">\n          <div className=\"navbar-brand\">\n            <a className=\"navbar-item\" href=\"https://myblog.com\">\n              <h1>My Blog</h1>\n            </a>\n            <div className=\"navbar-burger burger\">\n              <span />\n              <span />\n              <span />\n            </div>\n          </div>\n          <div className=\"navbar-menu\">\n            <div className=\"navbar-start\">\n              <a className=\"navbar-item\" href=\"/home\"> Home </a>\n              <a className=\"navbar-item\" href=\"/posts\"> Posts </a>\n            </div>\n          </div>\n        </nav>\n      </header>\n    </div>\n  </div>\n  <div className=\"container\">\n    <div className=\"columns\">\n      <div className=\"column is-8\">\n        <List>\n          <h1 className=\"title\">Latest posts</h1>\n          <div className=\"box\">\n            <ActionButton text=\"Sort\" callback=\"{[Function]}\">\n              <button className=\"button is-primary\" onClick=\"{[Function]}\">\n                Sort\n              </button>\n            </ActionButton>\n          </div>\n          <div id=\"boxDiv\" className=\"box\">\n            <Post post=\"{{...}}\">\n              <div className=\"panel\">\n                <p className=\"panel-heading\">Post1</p>\n                <section className=\"panel-block\">\n                  <p>Hello</p>\n                </section>\n              </div>\n            </Post>\n            <Post post=\"{{...}}\">\n              <div className=\"panel\">\n                <p className=\"panel-heading\">Post2</p>\n                <section className=\"panel-block\">\n                  <p>Hello</p>\n                </section>\n              </div>\n            </Post>\n            <Post post=\"{{...}}\">\n              <div className=\"panel\">\n                <p className=\"panel-heading\">Post3</p>\n                <section className=\"panel-block\">\n                  <p>Hello</p>\n                </section>\n              </div>\n            </Post>\n            <Post post=\"{{...}}\">\n              <div className=\"panel\">\n                <p className=\"panel-heading\">Post4</p>\n                <section className=\"panel-block\">\n                  <p>Hello</p>\n                </section>\n              </div>\n            </Post>\n          </div>\n        </List>\n      </div>\n      <div className=\"column is-4\">\n        <AuthorList>\n          <h1 className=\"title\">Authors</h1>\n          <ul className=\"list\">\n            <a href=\"/\" className=\"list-item\"> Sirwan Afifi </a>\n          </ul>\n        </AuthorList>\n      </div>\n    </div>\n  </div>\n</App>
","metadata":{"headings":[{"depth":1,"slug":"shallow-rendering","text":"Shallow rendering"},{"depth":1,"slug":"full-rendering","text":"Full rendering"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Testing React Components","date":"2019-10-02T23:46:37.121Z","template":"post","draft":false,"slug":"Testing-React-Components/","tags":["React"],"category":"Programming","description":"Testing React components is a crucial part of the development process. It helps us to make sure that our components are working as expected.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Testing-React-Components/"},{"id":"en/2019-10-27-Flux.md","data":{"title":"Flux","date":"2019-10-27T23:46:37.121Z","description":"A design pattern developed at Facebook to keep data flowing in one direction (unidirectional data flow)","template":"post","draft":false,"tags":["React","Programming Notes"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"# What's Flux?\n\n- A design pattern developed at Facebook to keep data flowing in one direction (unidirectional data flow)\n- An alternative to MVC\n- Provides a way to provide data that React will use to create the UI\n\n# Definitions:\n\n- Store: In flux, application state data in managed outside of React components in stores.\n- Store holds and change data\n- Stores are the only thing that can update a view in Flux\n- An action provides the instructions and data required to make a change.\n- Actions are dispatched using a central control component called dispatcher.\n- The dispatcher is designed to queue up actions and dispatch them to the appropriate store.\n- Every change requires an action.\n- Action creators are functions that can be used to abstract away the nitty-gritty details required to build an action.\n- Actions are object that at minimum contain a type field\n- Dispatcher takes an action, packages it with some information and send it on to the appropriate store.\n\n\n\n> Structure and Data Flow\n> https://facebook.github.io/flux/docs/in-depth-overview/\n\n# Flux implementations\n\n- Flux (https://facebook.github.io/flux/)\n- Reflux (https://github.com/reflux/refluxjs)\n- Flummox (http://acdlite.github.io/flummox)\n- Fluxible (https://fluxible.io/)\n- Redux (https://redux.js.org/)\n- MobX (https://mobx.js.org/README.html)","filePath":"src/content/blog/en/2019-10-27-Flux.md","assetImports":["./covers/cover.png"],"digest":"1c6f84de4bf5c809","rendered":{"html":"

What’s Flux?

\n
    \n
  • A design pattern developed at Facebook to keep data flowing in one direction (unidirectional data flow)
  • \n
  • An alternative to MVC
  • \n
  • Provides a way to provide data that React will use to create the UI
  • \n
\n

Definitions:

\n
    \n
  • Store: In flux, application state data in managed outside of React components in stores.
  • \n
  • Store holds and change data
  • \n
  • Stores are the only thing that can update a view in Flux
  • \n
  • An action provides the instructions and data required to make a change.
  • \n
  • Actions are dispatched using a central control component called dispatcher.
  • \n
  • The dispatcher is designed to queue up actions and dispatch them to the appropriate store.
  • \n
  • Every change requires an action.
  • \n
  • Action creators are functions that can be used to abstract away the nitty-gritty details required to build an action.
  • \n
  • Actions are object that at minimum contain a type field
  • \n
  • Dispatcher takes an action, packages it with some information and send it on to the appropriate store.
  • \n
\n\n
\n

Structure and Data Flow\nhttps://facebook.github.io/flux/docs/in-depth-overview/

\n
\n

Flux implementations

\n","metadata":{"headings":[{"depth":1,"slug":"whats-flux","text":"What’s Flux?"},{"depth":1,"slug":"definitions","text":"Definitions:"},{"depth":1,"slug":"flux-implementations","text":"Flux implementations"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Flux","date":"2019-10-27T23:46:37.121Z","template":"post","draft":false,"slug":"Flux/","tags":["React","Programming Notes"],"category":"Programming","description":"A design pattern developed at Facebook to keep data flowing in one direction (unidirectional data flow)","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Flux/"},{"id":"en/2019-10-21-Building-Ionic-React-App.md","data":{"title":"Building Ionic React App","date":"2019-10-21T23:46:37.121Z","description":"Ionic is a cross-platform mobile app development framework built on top of Angular. It allows you to build mobile apps using web technologies like HTML, CSS, and JavaScript...","template":"post","draft":false,"tags":["React","Ionic","Programming Notes"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"1. Make sure you have Node.js installed (https://nodejs.org/dist/v12.13.0/node-v12.13.0-x86.msi)\n2. Open command prompt and type in this command to create an app: npx ionic start myApp blank --type=react\n3. Make sure you have VSCode installed (https://code.visualstudio.com/download)\n4. cd into myApp\n5. Type in this command to open the project in VSCode: code .\n6. Inside App.tsx you can see something like this:\n ``\n This means that when we navigate to /home it shows a page called Home which is located inside pages directory.\n7. Run the project using this command: npx ionic serve\n8. Switch to the editor and create a new page called List.tsx with this content:\n\n```js\nimport {\n IonContent,\n IonHeader,\n IonPage,\n IonTitle,\n IonToolbar,\n} from \"@ionic/react\";\nimport React from \"react\";\n\nconst List: React.FC = () => {\n return (\n \n \n \n This is a sample page\n \n \n \n {[\"Item one\", \"Item two\", \"Item 3\"].map((item) => (\n

{item}

\n ))}\n
\n
\n );\n};\n\nexport default List;\n```\n\n9. Add a new route for the newly created page inside App.tsx right after the ``:\n\n```js\n\n```\n\n\"ionic\"","filePath":"src/content/blog/en/2019-10-21-Building-Ionic-React-App.md","assetImports":["./covers/cover.png"],"digest":"4469fbc3e36e7715","rendered":{"html":"
    \n
  1. Make sure you have Node.js installed (https://nodejs.org/dist/v12.13.0/node-v12.13.0-x86.msi)
  2. \n
  3. Open command prompt and type in this command to create an app: npx ionic start myApp blank —type=react
  4. \n
  5. Make sure you have VSCode installed (https://code.visualstudio.com/download)
  6. \n
  7. cd into myApp
  8. \n
  9. Type in this command to open the project in VSCode: code .
  10. \n
  11. Inside App.tsx you can see something like this:\n<Route path=\"/home\" component={Home} exact={true} />\nThis means that when we navigate to /home it shows a page called Home which is located inside pages directory.
  12. \n
  13. Run the project using this command: npx ionic serve
  14. \n
  15. Switch to the editor and create a new page called List.tsx with this content:
  16. \n
\n
import {\n  IonContent,\n  IonHeader,\n  IonPage,\n  IonTitle,\n  IonToolbar,\n} from \"@ionic/react\";\nimport React from \"react\";\n\nconst List: React.FC = () => {\n  return (\n    <IonPage>\n      <IonHeader>\n        <IonToolbar>\n          <IonTitle>This is a sample page</IonTitle>\n        </IonToolbar>\n      </IonHeader>\n      <IonContent className=\"ion-padding\">\n        {[\"Item one\", \"Item two\", \"Item 3\"].map((item) => (\n          <p key={item}>{item}</p>\n        ))}\n      </IonContent>\n    </IonPage>\n  );\n};\n\nexport default List;
\n
    \n
  1. Add a new route for the newly created page inside App.tsx right after the <Route path=\"/home\" component={Home} exact={true} />:
  2. \n
\n
<Route path=\"/list\" component={List} exact={true} />
\n\"ionic\"","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Building Ionic React App","date":"2019-10-21T23:46:37.121Z","template":"post","draft":false,"slug":"Building-Ionic-React-App/","tags":["React","Ionic","Programming Notes"],"category":"Programming","description":"Ionic is a cross-platform mobile app development framework built on top of Angular. It allows you to build mobile apps using web technologies like HTML, CSS, and JavaScript...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Building-Ionic-React-App/"},{"id":"en/2019-10-29-React.md","data":{"title":"Initializing state using class field declaration","date":"2019-10-29T23:46:37.121Z","description":"If you want to initialize state in a class based component we have two options: In constructor As a class property","template":"post","draft":false,"tags":["React"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"If you want to initialize state in a class based component we have two options:\n\n- In constructor\n- As a class property\n\nFor class based components I used to initialize state in the constructor:\n\n```js\nimport React, { Component } from \"react\";\n\nexport class SampleComponent extends Component {\n constructor(props) {\n super(props);\n this.state = {\n items: [\n { id: this.getRandomInt(5), name: \"Item 1\" },\n { id: this.getRandomInt(5), name: \"Item 2\" },\n ],\n };\n }\n\n getRandomInt = (max) => {\n return Math.floor(Math.random() * Math.floor(max));\n };\n\n render() {\n return (\n
    \n                 \n {this.state.items.map((item) => (\n
  • \n {item.name} - {item.id}\n
  • \n ))}\n             \n
\n );\n }\n}\n```\n\nThis approach is fine, but you will have to make sure you call `super(props)`. Sometimes we might forget to call `super(props)` in the constructor; in this case, the parent's constructor won't be executed, which will cause the following error:\n\n> ReferenceError: Must call the `super(props)` constructor in derived class before accessing 'this' or returning from derived constructor\n\nIt's where using class field declaration comes in handy. It saves us a few keystrokes, so you don't need to worry about calling `super(props)` anymore. So the previous example can be written as:\n\n```js\nimport React, { Component } from \"react\";\n\nexport class SampleComponent extends Component {\n getRandomInt = (max) => {\n return Math.floor(Math.random() * Math.floor(max));\n };\n\n state = {\n items: [\n { id: this.getRandomInt(5), name: \"Item 1\" },\n { id: this.getRandomInt(5), name: \"Item 2\" },\n ],\n };\n\n render() {\n return (\n
    \n                 \n {this.state.items.map((item) => (\n
  • \n {item.name} - {item.id}\n
  • \n ))}\n             \n
\n );\n }\n}\n```\n\nThe key point to remember here is that if you are going to call a method inside the `state` (`getRandomInt` in our case), you must declare your methods before declaring the state otherwise you will get the following error:\n\n> TypeError: this.getRandomInt is not a function\n\nIf you are using TypeScript then it has got your back and immediately yelling at you:\n\n","filePath":"src/content/blog/en/2019-10-29-React.md","assetImports":["./covers/cover.png"],"digest":"bf36894d5e94b273","rendered":{"html":"

If you want to initialize state in a class based component we have two options:

\n
    \n
  • In constructor
  • \n
  • As a class property
  • \n
\n

For class based components I used to initialize state in the constructor:

\n
import React, { Component } from \"react\";\n\nexport class SampleComponent extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      items: [\n        { id: this.getRandomInt(5), name: \"Item 1\" },\n        { id: this.getRandomInt(5), name: \"Item 2\" },\n      ],\n    };\n  }\n\n  getRandomInt = (max) => {\n    return Math.floor(Math.random() * Math.floor(max));\n  };\n\n  render() {\n    return (\n      <ul>\n                        \n        {this.state.items.map((item) => (\n          <li key={item.id}>\n            {item.name} - {item.id}\n          </li>\n        ))}\n                    \n      </ul>\n    );\n  }\n}
\n

This approach is fine, but you will have to make sure you call super(props). Sometimes we might forget to call super(props) in the constructor; in this case, the parent’s constructor won’t be executed, which will cause the following error:

\n
\n

ReferenceError: Must call the super(props) constructor in derived class before accessing ‘this’ or returning from derived constructor

\n
\n

It’s where using class field declaration comes in handy. It saves us a few keystrokes, so you don’t need to worry about calling super(props) anymore. So the previous example can be written as:

\n
import React, { Component } from \"react\";\n\nexport class SampleComponent extends Component {\n  getRandomInt = (max) => {\n    return Math.floor(Math.random() * Math.floor(max));\n  };\n\n  state = {\n    items: [\n      { id: this.getRandomInt(5), name: \"Item 1\" },\n      { id: this.getRandomInt(5), name: \"Item 2\" },\n    ],\n  };\n\n  render() {\n    return (\n      <ul>\n                        \n        {this.state.items.map((item) => (\n          <li key={item.id}>\n            {item.name} - {item.id}\n          </li>\n        ))}\n                    \n      </ul>\n    );\n  }\n}
\n

The key point to remember here is that if you are going to call a method inside the state (getRandomInt in our case), you must declare your methods before declaring the state otherwise you will get the following error:

\n
\n

TypeError: this.getRandomInt is not a function

\n
\n

If you are using TypeScript then it has got your back and immediately yelling at you:

\n","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Initializing state using class field declaration","date":"2019-10-29T23:46:37.121Z","template":"post","draft":false,"slug":"Initializing-state-using-class-field-declaration/","tags":["React"],"category":"Programming","description":"If you want to initialize state in a class based component we have two options: In constructor As a class property","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Initializing-state-using-class-field-declaration/"},{"id":"en/2019-04-09-Hosting-react-app-on-iis.md","data":{"title":"Hosting React app on IIS","date":"2019-04-09T23:46:37.121Z","description":"Today I wanted to host a React application; the first and easiest option was hosting the app using a package called serve which is basically a static file serving tool. The process was easy, all I had to do was first prepare a production build of my application using npm run build then run the npx serve command inside my build's directory...","template":"post","draft":false,"tags":["React.js","Routing","IIS"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Today I wanted to host a React application; the first and easiest option was hosting the app using a package called [serve](https://github.com/zeit/serve) which is basically a static file serving tool. The process was easy, all I had to do was first prepare a production build of my application using `npm run build` then run the `npx serve` command inside my build's directory:\n\n```js\ncd build\nserve -s\n```\n\nThis is great but the problem is that my application is using React Router and when I wanted to navigate between pages I got `404` error:\n\n\"React\n\nbased on the officail React docs:\n\n> If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not. This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html\n\nSo I decided to host the app on IIS and define a URL rewrite to redirect all unknown paths to `index.html`. URL Rewrite isn't installed by defualt so you must [install](https://www.iis.net/downloads/microsoft/url-rewrite) it if you haven't already. Here's what I did to host my React application:\n\n1- Adding a new website on IIS\n\n\"Create\n\n2- Adding the following rule to URL rewrite:\n\n\"URL\n\nAs you know, this configuration is also saved in somewhere else which is the location of the newly created website inside a file called `web.config`, So this means that what we created in the UI is generated into this XML file. If we open up the file, we can see the following configuration:\n\n```xml\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n```\n\nThe critical part is inside the `rules` tag. The tag name is an arbitrary string you can change it to whatever you want, and then we have a pattern `.*` Which means everything using regular expression syntax, then we have our rules, we are basically saying if the input contains a file name or a directory name at the end of URL, an action occurs in this case the action is redirecting to `index.html`. You might be wondering why I set `stopProcessing=\"true\"`, by setting this flag to true it will stop the processing of further rules, and the request will be passed to the IIS request pipeline. Now the unknown paths are handed off to the client side router, and the rest is history.","filePath":"src/content/blog/en/2019-04-09-Hosting-react-app-on-iis.md","assetImports":["./covers/cover.png"],"digest":"a424d70f5dd9c392","rendered":{"html":"

Today I wanted to host a React application; the first and easiest option was hosting the app using a package called serve which is basically a static file serving tool. The process was easy, all I had to do was first prepare a production build of my application using npm run build then run the npx serve command inside my build’s directory:

\n
cd build\nserve -s
\n

This is great but the problem is that my application is using React Router and when I wanted to navigate between pages I got 404 error:

\n\"React\n

based on the officail React docs:

\n
\n

If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not. This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html

\n
\n

So I decided to host the app on IIS and define a URL rewrite to redirect all unknown paths to index.html. URL Rewrite isn’t installed by defualt so you must install it if you haven’t already. Here’s what I did to host my React application:

\n

1- Adding a new website on IIS

\n\"Create\n

2- Adding the following rule to URL rewrite:

\n\"URL\n

As you know, this configuration is also saved in somewhere else which is the location of the newly created website inside a file called web.config, So this means that what we created in the UI is generated into this XML file. If we open up the file, we can see the following configuration:

\n
<?xml version=\"1.0\"?>\n<configuration>\n    <system.webServer>\n        <rewrite>\n            <rules>\n                <rule name=\"React Routes\" stopProcessing=\"true\">\n                    <match url=\".*\" />\n                    <conditions logicalGrouping=\"MatchAll\">\n                        <add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" negate=\"true\" />\n                        <add input=\"{REQUEST_FILENAME}\" matchType=\"IsDirectory\" negate=\"true\" />\n                    </conditions>\n                    <action type=\"Rewrite\" url=\"/index.html\" />\n                </rule>\n            </rules>\n        </rewrite>\n    </system.webServer>\n</configuration>
\n

The critical part is inside the rules tag. The tag name is an arbitrary string you can change it to whatever you want, and then we have a pattern .* Which means everything using regular expression syntax, then we have our rules, we are basically saying if the input contains a file name or a directory name at the end of URL, an action occurs in this case the action is redirecting to index.html. You might be wondering why I set stopProcessing=\"true\", by setting this flag to true it will stop the processing of further rules, and the request will be passed to the IIS request pipeline. Now the unknown paths are handed off to the client side router, and the rest is history.

","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Hosting React app on IIS","date":"2019-04-09T23:46:37.121Z","template":"post","draft":false,"slug":"Hosting-react-app-on-iis/","tags":["React.js","Routing","IIS"],"category":"Programming","description":"Today I wanted to host a React application; the first and easiest option was hosting the app using a package called serve which is basically a static file serving tool. The process was easy, all I had to do was first prepare a production build of my application using npm run build then run the npx serve command inside my build's directory...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Hosting-react-app-on-iis/"},{"id":"en/2019-03-07-Hosting-WCF-Service.md","data":{"title":"Hosting a WCF Service as a Windows Service Using Topshelf","date":"2019-03-07T23:46:37.121Z","description":"You might be wondering why I am blogging about WCF. Is it still relevant? This is part of a legacy WCF project, and I am responsible for adding some functionalities to it, I like it though. By the way, it's been a long time since it went out of fashion, but many large enterprise applications still use it.","template":"post","draft":false,"tags":["C#","WCF"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"You might be wondering why I am blogging about WCF. Is it still relevant? This is part of a legacy WCF project, and I am responsible for adding some functionalities to it, I like it though. By the way, it's been a long time since it went out of fashion, but many large enterprise applications still use it.\n\nAs you know, WCF services need to run in a host process so when clients want to consume the services we need to make sure the services are alive. The host process needs to provide a host, and this host is responsible for setting up the services and listening for incoming messages then creating instances of the service and respond to the client by dispatching a call to the service class. As I mentioned in a legacy application we wanted to host our services as a Windows Service, this app had been using a Console application, but the problem with Console applications is that you need to make sure the app is open all the time. For example, if the server gets restarted you should manually open the app, you could say we should add this app as a startup process so whenever the system boots up this app is opened but we can achieve a better result by writing a Windows service instead. Windows services are a great way to run code in the background; this means that we don’t need a Console Application to run the application. Once you installed the service it keeps running, we can control how to start the service for example when can set it to automatically started when the system boots or be configured when a user logs in. Both of these approaches are considered as two hosting options because they are self-hosted applications; it means that both are running inside a .NET process.\n\n## Installing Topshelf\n\nTopshelf is an open source .NET Windows Service library, it makes the process of creating Windows services much easier for us so that we can only focus on the service functionality as opposed to setting up the boilerplate service code. To install TopShelf all we need to do is installing its NuGet package:\n\n```\nInstall-Package Topshelf\n```\n\nThe next step is wrapping your service functionality inside a class with two methods `Start` and `Stop` these methods are going to be used by TopShelf to start and stop the service:\n\n```csharp\npublic class MyService\n{\n private ServiceHost usersHost;\n\n public bool Start()\n {\n\n try\n {\n usersHost = new ServiceHost(typeof(UsersService.UsersService));\n\n usersHost.Open();\n Console.WriteLine(\"Service Running...\");\n Console.WriteLine(\"Press a key to quit\");\n\n return true;\n }\n catch (Exception ex)\n {\n\n return false;\n }\n finally\n {\n usersHost.Close();\n }\n }\n\n public bool Stop()\n {\n usersHost.Close();\n\n return true;\n }\n}\n```\n\nThe next step is adding this class to TopShelf for creating our Windows Service:\n\n```csharp\npublic class Program\n{\n static void Main(string[] args)\n {\n HostFactory.Run(serviceConfig =>\n {\n serviceConfig.Service(serviceInstance =>\n {\n serviceInstance.ConstructUsing(() => new MyService());\n serviceInstance.WhenStarted(execute => execute.Start());\n serviceInstance.WhenStopped(execute => execute.Stop());\n });\n\n serviceConfig.SetServiceName(\"My Service\");\n serviceConfig.SetDisplayName(\"My Service\");\n serviceConfig.SetDescription(\"Hosting WCF services\");\n\n serviceConfig.StartAutomatically();\n });\n }\n}\n```\n\n## Installing our service into Windows\n\n- Run Command Prompt as Admin\n- cd into to bin\\Debug folder\n- {AssebmlyName}.exe install\n\n## Adding NLog\n\nWe can add logging functionality to the mix using NLog, for doing so we first need to add the following package:\n\n```\nInstall-Package Topshelf.NLog\n```\n\nThe next step is to add the following configuration to `app.config` file:\n\n```xml\n\n
\n\n\n\n \n \n \n \n \n \n\n```\n\nThen we need to register NLog service in the `Program.cs` file:\n\n```csharp\npublic class Program\n{\n static void Main(string[] args)\n {\n HostFactory.Run(serviceConfig =>\n {\n serviceConfig.UseNLog();\n\n // as before\n });\n }\n}\n```\n\nNow we can use the logger in our service:\n\n```csharp\npublic class MyService\n{\n // our service declarations\n\n private static readonly LogWriter _log = HostLogger.Get();\n\n public bool Start()\n {\n try\n {\n _log.Info(\"Starting services\");\n\n```","filePath":"src/content/blog/en/2019-03-07-Hosting-WCF-Service.md","assetImports":["./covers/cover.png"],"digest":"13145057be3658b5","rendered":{"html":"

You might be wondering why I am blogging about WCF. Is it still relevant? This is part of a legacy WCF project, and I am responsible for adding some functionalities to it, I like it though. By the way, it’s been a long time since it went out of fashion, but many large enterprise applications still use it.

\n

As you know, WCF services need to run in a host process so when clients want to consume the services we need to make sure the services are alive. The host process needs to provide a host, and this host is responsible for setting up the services and listening for incoming messages then creating instances of the service and respond to the client by dispatching a call to the service class. As I mentioned in a legacy application we wanted to host our services as a Windows Service, this app had been using a Console application, but the problem with Console applications is that you need to make sure the app is open all the time. For example, if the server gets restarted you should manually open the app, you could say we should add this app as a startup process so whenever the system boots up this app is opened but we can achieve a better result by writing a Windows service instead. Windows services are a great way to run code in the background; this means that we don’t need a Console Application to run the application. Once you installed the service it keeps running, we can control how to start the service for example when can set it to automatically started when the system boots or be configured when a user logs in. Both of these approaches are considered as two hosting options because they are self-hosted applications; it means that both are running inside a .NET process.

\n

Installing Topshelf

\n

Topshelf is an open source .NET Windows Service library, it makes the process of creating Windows services much easier for us so that we can only focus on the service functionality as opposed to setting up the boilerplate service code. To install TopShelf all we need to do is installing its NuGet package:

\n
Install-Package Topshelf
\n

The next step is wrapping your service functionality inside a class with two methods Start and Stop these methods are going to be used by TopShelf to start and stop the service:

\n
public class MyService\n{\n    private ServiceHost usersHost;\n\n    public bool Start()\n    {\n\n        try\n        {\n            usersHost = new ServiceHost(typeof(UsersService.UsersService));\n\n            usersHost.Open();\n            Console.WriteLine(\"Service Running...\");\n            Console.WriteLine(\"Press a key to quit\");\n\n            return true;\n        }\n        catch (Exception ex)\n        {\n\n            return false;\n        }\n        finally\n        {\n            usersHost.Close();\n        }\n    }\n\n    public bool Stop()\n    {\n        usersHost.Close();\n\n        return true;\n    }\n}
\n

The next step is adding this class to TopShelf for creating our Windows Service:

\n
public class Program\n{\n    static void Main(string[] args)\n    {\n        HostFactory.Run(serviceConfig =>\n        {\n            serviceConfig.Service<MyService>(serviceInstance =>\n            {\n                serviceInstance.ConstructUsing(() => new MyService());\n                serviceInstance.WhenStarted(execute => execute.Start());\n                serviceInstance.WhenStopped(execute => execute.Stop());\n            });\n\n            serviceConfig.SetServiceName(\"My Service\");\n            serviceConfig.SetDisplayName(\"My Service\");\n            serviceConfig.SetDescription(\"Hosting WCF services\");\n\n            serviceConfig.StartAutomatically();\n        });\n    }\n}
\n

Installing our service into Windows

\n
    \n
  • Run Command Prompt as Admin
  • \n
  • cd into to bin\\Debug folder
  • \n
  • {AssebmlyName}.exe install
  • \n
\n

Adding NLog

\n

We can add logging functionality to the mix using NLog, for doing so we first need to add the following package:

\n
Install-Package Topshelf.NLog
\n

The next step is to add the following configuration to app.config file:

\n
<configSections>\n   <section name=\"nlog\" type=\"NLog.Config.ConfigSectionHandler, NLog\"/>\n</configSections>\n\n<nlog>\n    <targets>\n      <target name=\"consoleTarget\" type=\"Console\" />\n    </targets>\n    <rules>\n      <logger name=\"*\" minlevel=\"Debug\" writeTo=\"consoleTarget\" />\n    </rules>\n</nlog>
\n

Then we need to register NLog service in the Program.cs file:

\n
public class Program\n{\n    static void Main(string[] args)\n    {\n        HostFactory.Run(serviceConfig =>\n        {\n            serviceConfig.UseNLog();\n\n            // as before\n        });\n    }\n}
\n

Now we can use the logger in our service:

\n
public class MyService\n{\n    // our service declarations\n\n    private static readonly LogWriter _log = HostLogger.Get<MyService>();\n\n     public bool Start()\n        {\n            try\n            {\n               _log.Info(\"Starting services\");\n
","metadata":{"headings":[{"depth":2,"slug":"installing-topshelf","text":"Installing Topshelf"},{"depth":2,"slug":"installing-our-service-into-windows","text":"Installing our service into Windows"},{"depth":2,"slug":"adding-nlog","text":"Adding NLog"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Hosting a WCF Service as a Windows Service Using Topshelf","date":"2019-03-07T23:46:37.121Z","template":"post","draft":false,"slug":"Hosting-WCF-Service/","tags":["C#","WCF"],"category":"Programming","description":"You might be wondering why I am blogging about WCF. Is it still relevant? This is part of a legacy WCF project, and I am responsible for adding some functionalities to it, I like it though. By the way, it's been a long time since it went out of fashion, but many large enterprise applications still use it.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Hosting-WCF-Service/"},{"id":"en/2019-08-09-Using-IHostingEnvironment-in-a-test-project.md","data":{"title":"Using IHostingEnvironment in a test project","date":"2019-08-09T23:46:37.121Z","description":"Assume that you have a service which accepts IHostingEnvironment as its dependency...","template":"post","draft":false,"tags":["ASP.NET Core","xUnit",".NET Core"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Assume that you have a service which accepts `IHostingEnvironment` as its dependency:\n\n```csharp\npublic class MyService\n{\n private readonly IHostingEnvironment hostingEnv;\n\n public MyService(IHostingEnvironment hostingEnv)\n {\n this.hostingEnv = hostingEnv;\n }\n\n public Task> GetPosts()\n {\n var fileInfo = hostingEnv.ContentRootFileProvider.GetFileInfo(\"posts.json\");\n var file = File.ReadAllText(file.PhysicalPath);\n var deserializeObject = JsonConvert.DeserializeObject>(file);\n return Task.FromResult(deserializeObject);\n }\n}\n```\n\nNow we wan to be able to load that JSON file inside a test project in order to test the service. First of all, we need to make sure we have these packages installed on the test project:\n\n```xml\n\n    \n    \n    \n    \n    \n    \n    \n    \n\n```\n\nWe also need to modify the csproj file to copy the JSON file to the build output:\n\n```xml\n\n    \n        PreserveNewest\n    \n\n```\n\nThen we need a base class to configure the built-in DI container and register `IHostingEnvironment`:\n\n```csharp\nnamespace GreatSpot.Tests\n{\n    public class BaseTest\n    {\n        public static IServiceProvider Services { get; private set; }\n        public BaseTest()\n        {\n            var serviceCollection = new ServiceCollection();\n            serviceCollection.AddSingleton(new HostingEnvironment\n            {\n                ContentRootFileProvider = new PhysicalFileProvider(Environment.CurrentDirectory)\n            });\n            Services = serviceCollection.BuildServiceProvider();\n        }\n    }\n}\n```\n\nNow we can use the registred service in our test methods:\n\n```csharp\npublic class PostTests : BaseTest\n{\n [Fact]\n public async Task Get_All_Posts()\n {\n     var hostingEnvironment = Services.GetService();\n\n     var myService = new MyService(hostingEnvironment);\n     var data = await myService.GetPosts();\n     Assert.Equal(10, data.Count);\n }\n}\n```","filePath":"src/content/blog/en/2019-08-09-Using-IHostingEnvironment-in-a-test-project.md","assetImports":["./covers/cover.png"],"digest":"2a14f5dd253d7ddd","rendered":{"html":"

Assume that you have a service which accepts IHostingEnvironment as its dependency:

\n
public class MyService\n{\n    private readonly IHostingEnvironment hostingEnv;\n\n    public MyService(IHostingEnvironment hostingEnv)\n    {\n        this.hostingEnv = hostingEnv;\n    }\n\n    public Task<IEnumerable<Post>> GetPosts()\n    {\n        var fileInfo = hostingEnv.ContentRootFileProvider.GetFileInfo(\"posts.json\");\n        var file = File.ReadAllText(file.PhysicalPath);\n        var deserializeObject = JsonConvert.DeserializeObject<IEnumerable<Post>>(file);\n        return Task.FromResult(deserializeObject);\n    }\n}
\n

Now we wan to be able to load that JSON file inside a test project in order to test the service. First of all, we need to make sure we have these packages installed on the test project:

\n
<ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Hosting\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Hosting.Abstractions\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.Extensions.DependencyInjection\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.Extensions.FileProviders.Physical\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"16.0.1\" />\n    <PackageReference Include=\"xunit\" Version=\"2.4.0\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"2.4.0\" />\n</ItemGroup>
\n

We also need to modify the csproj file to copy the JSON file to the build output:

\n
<ItemGroup>\n    <None Update=\"data.json\">\n        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n</ItemGroup>
\n

Then we need a base class to configure the built-in DI container and register IHostingEnvironment:

\n
namespace GreatSpot.Tests\n{\n    public class BaseTest\n    {\n        public static IServiceProvider Services { get; private set; }\n        public BaseTest()\n        {\n            var serviceCollection = new ServiceCollection();\n            serviceCollection.AddSingleton<IHostingEnvironment>(new HostingEnvironment\n            {\n                ContentRootFileProvider = new PhysicalFileProvider(Environment.CurrentDirectory)\n            });\n            Services = serviceCollection.BuildServiceProvider();\n        }\n    }\n}
\n

Now we can use the registred service in our test methods:

\n
public class PostTests : BaseTest\n{\n    [Fact]\n    public async Task Get_All_Posts()\n    {\n        var hostingEnvironment = Services.GetService<IHostingEnvironment>();\n\n        var myService = new MyService(hostingEnvironment);\n        var data = await myService.GetPosts();\n        Assert.Equal(10, data.Count);\n    }\n}
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Using IHostingEnvironment in a test project","date":"2019-08-09T23:46:37.121Z","template":"post","draft":false,"slug":"Using-IHostingEnvironment-in-a-test-project/","tags":["ASP.NET Core","xUnit",".NET Core"],"category":"Programming","description":"Assume that you have a service which accepts IHostingEnvironment as its dependency...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Using-IHostingEnvironment-in-a-test-project/"},{"id":"en/2019-09-18-Importing-JSON-files-into-SQL-SERVER.md","data":{"title":"Importing JSON files into SQL Server","date":"2019-09-18T23:46:37.121Z","description":"I was assigned to a task to import a GeoJSON file into a SQL Server database. The file was pretty big; I couldn't even open the file in an editor. At first, I wanted to write a simple program (with C# or Python) to open the file and then loop through the entries, ...","template":"post","draft":false,"tags":["SQL Server","TSQL"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"I was assigned to a task to import a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) file into a SQL Server database. The file was pretty big; I couldn't even open the file in an editor. At first, I wanted to write a simple program (with C# or Python) to open the file and then loop through the entries, parse each one of the entry and then save it into the database. But it would have taken time if I followed that process. All I wanted to do was save a JSON file right into the database. That's where I gave `OPENROWSET` a try. Everything went well, and I successfully saved the file into the database:\n\n```sql\nDECLARE @GeoJSON nvarchar(max)\n\nSELECT @GeoJSON = BulkColumn\n FROM OPENROWSET (BULK 'C:\\areas.json', SINGLE_CLOB) as j\n\nINSERT INTO dbo.Areas (Area,Coordinates)\nSELECT\n\tArea,\n\tCoordinates\nFROM\n OPENJSON(@GeoJSON, '$.features')\n WITH (\n Area varchar(50) '$.properties.name',\n Coordinates nvarchar(max) '$.geometry.coordinates' as JSON\n )\n```\n\nAs you might already know, the `OPENROWSET` is a table value function which returns a table with a single column called `Bulk`. What above code does is first open the JSON file and assign it to a variable called `GeoJSON`. Then I used another table value column called `OPENJSON` to parse the JSON. The first thing we can do is to set our root element, which is `features` in my case. Then elements can be referenced with the prefix `$`. There are two important things to mention. First, if you want to save a JSON element into a string column you will need to make sure the column type is `nvarchar(max)` and you add `as JSON` inside the `WITH` clause for that specific column.\n\nYou can also build a geography value if you have a column with that type:\n\n```sql\nDECLARE @GeoJSON nvarchar(max)\n\nSELECT @GeoJSON = BulkColumn\n FROM OPENROWSET (BULK 'C:\\areas.json', SINGLE_CLOB) as j\n\nINSERT INTO dbo.Areas (Area,Coordinates)\nSELECT\n\tArea,\n\tCoordinates,\n geography::STPointFromText('POINT (' + Longitude + ' ' + Latitude + ')', 4326) AS Geography,\n Longitude,\n Latitude\nFROM\n OPENJSON(@GeoJSON, '$.features')\n WITH (\n Area varchar(50) '$.properties.name',\n Coordinates nvarchar(max) '$.geometry.coordinates' as JSON,\n Longitude varchar(100) '$.lon',\n Latitude varchar(100) '$.lat'\n )\n```","filePath":"src/content/blog/en/2019-09-18-Importing-JSON-files-into-SQL-SERVER.md","assetImports":["./covers/cover.png"],"digest":"3d11ad6da0f16428","rendered":{"html":"

I was assigned to a task to import a GeoJSON file into a SQL Server database. The file was pretty big; I couldn’t even open the file in an editor. At first, I wanted to write a simple program (with C# or Python) to open the file and then loop through the entries, parse each one of the entry and then save it into the database. But it would have taken time if I followed that process. All I wanted to do was save a JSON file right into the database. That’s where I gave OPENROWSET a try. Everything went well, and I successfully saved the file into the database:

\n
DECLARE @GeoJSON nvarchar(max)\n\nSELECT @GeoJSON = BulkColumn\n FROM OPENROWSET (BULK 'C:\\areas.json', SINGLE_CLOB) as j\n\nINSERT INTO dbo.Areas (Area,Coordinates)\nSELECT\n\tArea,\n\tCoordinates\nFROM\n    OPENJSON(@GeoJSON, '$.features')\n             WITH (\n                 Area varchar(50) '$.properties.name',\n                 Coordinates nvarchar(max) '$.geometry.coordinates' as JSON\n                 )
\n

As you might already know, the OPENROWSET is a table value function which returns a table with a single column called Bulk. What above code does is first open the JSON file and assign it to a variable called GeoJSON. Then I used another table value column called OPENJSON to parse the JSON. The first thing we can do is to set our root element, which is features in my case. Then elements can be referenced with the prefix $. There are two important things to mention. First, if you want to save a JSON element into a string column you will need to make sure the column type is nvarchar(max) and you add as JSON inside the WITH clause for that specific column.

\n

You can also build a geography value if you have a column with that type:

\n
DECLARE @GeoJSON nvarchar(max)\n\nSELECT @GeoJSON = BulkColumn\n FROM OPENROWSET (BULK 'C:\\areas.json', SINGLE_CLOB) as j\n\nINSERT INTO dbo.Areas (Area,Coordinates)\nSELECT\n\tArea,\n\tCoordinates,\n    geography::STPointFromText('POINT (' + Longitude + ' ' + Latitude + ')', 4326) AS Geography,\n    Longitude,\n    Latitude\nFROM\n    OPENJSON(@GeoJSON, '$.features')\n             WITH (\n                 Area varchar(50) '$.properties.name',\n                 Coordinates nvarchar(max) '$.geometry.coordinates' as JSON,\n                 Longitude varchar(100) '$.lon',\n                 Latitude varchar(100) '$.lat'\n                 )
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Importing JSON files into SQL Server","date":"2019-09-18T23:46:37.121Z","template":"post","draft":false,"slug":"Importing-JSON-files-into-SQL-Server/","tags":["SQL Server","TSQL"],"category":"Programming","description":"I was assigned to a task to import a GeoJSON file into a SQL Server database. The file was pretty big; I couldn't even open the file in an editor. At first, I wanted to write a simple program (with C# or Python) to open the file and then loop through the entries, ...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Importing-JSON-files-into-SQL-Server/"},{"id":"en/2019-06-07-Calling-Stored-Procedures.md","data":{"title":"Calling Stored Procedures using Dapper","date":"2019-06-07T23:46:37.121Z","description":"Today I wanted to call a Stored Procedure using Entity Framework Core. It is possible using DbSet.FromSql() method, which is one of the powerful features of Entity Framework Core. It gives us the ability to run RAW SQL queries directly against a database...","template":"post","draft":false,"tags":["EF Core","Dapper","C#"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Today I wanted to call a Stored Procedure using Entity Framework Core. It is possible using `DbSet.FromSql()` method, which is one of the powerful features of Entity Framework Core. It gives us the ability to run RAW SQL queries directly against a database:\n\n```csharp\nvar blogs = context.Blogs\n .FromSql(\"CALL GetBlogs\")\n .ToList();\n```\n\nBut the problem is that the column names in the result set must match the column names that properties are mapped to. So, for example, given this Stored Procedure:\n\n```sql\nCREATE DEFINER=`root`@`%` PROCEDURE `GetBlogs`()\nBEGIN\n\tselect avg(Rating) as average, min(Rating)as minimum, max(Rating) as maximum\n\tfrom blogs\nEND\n```\n\nIn this case, your model must be exactly the same as the result set. Otherwise, you'd get an exception. Most of our Stored Procedure use some Aggregate functions. So I had to find another solution for it which was using Dapper. As you probably know, Dapper is nothing but a set of extension methods on top of `IDbConnection`. So to use it, you will need to install `Dapper` and register it using built-in IoC container in your ASP.NET Core application:\n\n```csharp\nservices.AddTransient((sp) => new MySqlConnection(configuration.GetConnectionString(\"MyConnection\")));\n\n```\n\nThen you can use it inside your services:\n\n```csharp\npublic class MyService\n{\n private readonly IDbConnection _dbConnection;\n\n public MyService(IDbConnection dbConnection)\n {\n _dbConnection = dbConnection;\n }\n\n public Task> GetBlogs(long authorId)\n {\n var query = _dbConnection.QueryAsync(\"GetBlogs\", new { AuthorId = authorId },\n commandType: CommandType.StoredProcedure);\n return query;\n }\n}\n```","filePath":"src/content/blog/en/2019-06-07-Calling-Stored-Procedures.md","assetImports":["./covers/cover.png"],"digest":"4dbad49a0f785d1e","rendered":{"html":"

Today I wanted to call a Stored Procedure using Entity Framework Core. It is possible using DbSet.FromSql() method, which is one of the powerful features of Entity Framework Core. It gives us the ability to run RAW SQL queries directly against a database:

\n
var blogs = context.Blogs\n    .FromSql(\"CALL GetBlogs\")\n    .ToList();
\n

But the problem is that the column names in the result set must match the column names that properties are mapped to. So, for example, given this Stored Procedure:

\n
CREATE DEFINER=`root`@`%` PROCEDURE `GetBlogs`()\nBEGIN\n\tselect avg(Rating) as average, min(Rating)as minimum, max(Rating) as maximum\n\tfrom blogs\nEND
\n

In this case, your model must be exactly the same as the result set. Otherwise, you’d get an exception. Most of our Stored Procedure use some Aggregate functions. So I had to find another solution for it which was using Dapper. As you probably know, Dapper is nothing but a set of extension methods on top of IDbConnection. So to use it, you will need to install Dapper and register it using built-in IoC container in your ASP.NET Core application:

\n
services.AddTransient<IDbConnection>((sp) => new MySqlConnection(configuration.GetConnectionString(\"MyConnection\")));\n
\n

Then you can use it inside your services:

\n
public class MyService\n{\n    private readonly IDbConnection _dbConnection;\n\n    public MyService(IDbConnection dbConnection)\n    {\n        _dbConnection = dbConnection;\n    }\n\n    public Task<IEnumerable<BlogViewModel>> GetBlogs(long authorId)\n    {\n        var query = _dbConnection.QueryAsync<BlogViewModel>(\"GetBlogs\", new { AuthorId = authorId },\n            commandType: CommandType.StoredProcedure);\n        return query;\n    }\n}
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Calling Stored Procedures using Dapper","date":"2019-06-07T23:46:37.121Z","template":"post","draft":false,"slug":"Calling-Stored-Procedures/","tags":["EF Core","Dapper","C#"],"category":"Programming","description":"Today I wanted to call a Stored Procedure using Entity Framework Core. It is possible using DbSet.FromSql() method, which is one of the powerful features of Entity Framework Core. It gives us the ability to run RAW SQL queries directly against a database...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Calling-Stored-Procedures/"},{"id":"en/2019-11-05-Redux.md","data":{"title":"Redux","date":"2019-11-05T23:46:37.121Z","description":"Redux is a predictable state container for JavaScript apps.","template":"post","draft":false,"tags":["Redux","React","Programming Notes"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"- Redux is a predictable state container for JavaScript apps.\n- The whole state of your app is stored in an object tree inside a single store.\n- The only way to change the state tree is to emit an action.\n- To specify how the actions transform the state tree, you write pure reducers:\n\n```js\nconst counter = (state = 0, action) => {\n switch (action.type) {\n case \"INCREMENT\":\n return state + 1;\n case \"DECREMENT\":\n return state - 1;\n default:\n return state;\n }\n};\n\nconst { createStore } = Redux;\nconst store = createStore(counter);\n\nconst render = () => {\n document.body.innerText = store.getState();\n};\n\nstore.subscribe(render);\nrender(); // calling once to render the initial state (0), then the subscribe will update subsequently\n\ndocument.addEventListener(\"click\", () => {\n store.dispatch({ type: \"INCREMENT\" });\n});\n```\n\n- Redux is very useful when you start getting a complicated data scenarios or complicate change of events.\n- It's really going to simplify your application:\n\n\"Redux\n\n- Setting up Redux is a bit confusing but once you set it up, it's going to pay off over the lifespan of the application.\n- Store is immutable, we can't mutate any value on the store, we only ever create a brand new store object:\n\n```js\nfunction createStore(reducer) {\n let state;\n let listeners = [];\n\n const getState = () => state;\n\n const subscribe = (listener) => {\n listeners.push(listener);\n return () => {\n listeners = listeners.filter((l) => l !== listeners);\n };\n };\n\n const dispatch = (action) => {\n state = reducer(state, action);\n listeners.forEach((listener) => listener());\n };\n\n return {\n getState,\n subscribe,\n dispatch,\n };\n}\n```\n\n- Subscribtions have to be added before dispatching actions.\n\n```js\n// Library code\nfunction createStore(reducer) {\n let state;\n let listeners = [];\n\n const getState = () => state;\n\n const subscribe = (listener) => {\n listeners.push(listener);\n return () => {\n listeners = listeners.filter((l) => l !== listener);\n };\n };\n\n const dispatch = (action) => {\n state = reducer(state, action);\n listeners.forEach((listener) => listener());\n };\n\n dispatch({});\n\n return {\n getState,\n subscribe,\n dispatch,\n };\n}\n\nconst INCREMENT = \"INCREMENT\";\nconst DECREMENT = \"DECREMENT\";\n\n// Reducers\nconst counter = (state = 0, action) => {\n switch (action.type) {\n case INCREMENT:\n return state + 1;\n case DECREMENT:\n return state - 1;\n default:\n return state;\n }\n};\n\nconst store = createStore(counter);\n\nconst unsubscribe = store.subscribe(() => {\n console.log(store.getState());\n});\n\n// Action creators\nfunction incrementAction() {\n return {\n type: INCREMENT,\n };\n}\nfunction decrementAction() {\n return {\n type: DECREMENT,\n };\n}\n\nstore.dispatch(incrementAction());\nstore.dispatch(incrementAction());\nstore.dispatch(incrementAction());\nstore.dispatch(decrementAction());\n```\n\n- We are going to wrap entire React application with one Provider component, So when the store changes it re-render the whole application.","filePath":"src/content/blog/en/2019-11-05-Redux.md","assetImports":["./covers/cover.png"],"digest":"79c3f87af35b2a12","rendered":{"html":"
    \n
  • Redux is a predictable state container for JavaScript apps.
  • \n
  • The whole state of your app is stored in an object tree inside a single store.
  • \n
  • The only way to change the state tree is to emit an action.
  • \n
  • To specify how the actions transform the state tree, you write pure reducers:
  • \n
\n
const counter = (state = 0, action) => {\n  switch (action.type) {\n    case \"INCREMENT\":\n      return state + 1;\n    case \"DECREMENT\":\n      return state - 1;\n    default:\n      return state;\n  }\n};\n\nconst { createStore } = Redux;\nconst store = createStore(counter);\n\nconst render = () => {\n  document.body.innerText = store.getState();\n};\n\nstore.subscribe(render);\nrender(); // calling once to render the initial state (0), then the subscribe will update subsequently\n\ndocument.addEventListener(\"click\", () => {\n  store.dispatch({ type: \"INCREMENT\" });\n});
\n
    \n
  • Redux is very useful when you start getting a complicated data scenarios or complicate change of events.
  • \n
  • It’s really going to simplify your application:
  • \n
\n\"Redux\n
    \n
  • Setting up Redux is a bit confusing but once you set it up, it’s going to pay off over the lifespan of the application.
  • \n
  • Store is immutable, we can’t mutate any value on the store, we only ever create a brand new store object:
  • \n
\n
function createStore(reducer) {\n  let state;\n  let listeners = [];\n\n  const getState = () => state;\n\n  const subscribe = (listener) => {\n    listeners.push(listener);\n    return () => {\n      listeners = listeners.filter((l) => l !== listeners);\n    };\n  };\n\n  const dispatch = (action) => {\n    state = reducer(state, action);\n    listeners.forEach((listener) => listener());\n  };\n\n  return {\n    getState,\n    subscribe,\n    dispatch,\n  };\n}
\n
    \n
  • Subscribtions have to be added before dispatching actions.
  • \n
\n
// Library code\nfunction createStore(reducer) {\n  let state;\n  let listeners = [];\n\n  const getState = () => state;\n\n  const subscribe = (listener) => {\n    listeners.push(listener);\n    return () => {\n      listeners = listeners.filter((l) => l !== listener);\n    };\n  };\n\n  const dispatch = (action) => {\n    state = reducer(state, action);\n    listeners.forEach((listener) => listener());\n  };\n\n  dispatch({});\n\n  return {\n    getState,\n    subscribe,\n    dispatch,\n  };\n}\n\nconst INCREMENT = \"INCREMENT\";\nconst DECREMENT = \"DECREMENT\";\n\n// Reducers\nconst counter = (state = 0, action) => {\n  switch (action.type) {\n    case INCREMENT:\n      return state + 1;\n    case DECREMENT:\n      return state - 1;\n    default:\n      return state;\n  }\n};\n\nconst store = createStore(counter);\n\nconst unsubscribe = store.subscribe(() => {\n  console.log(store.getState());\n});\n\n// Action creators\nfunction incrementAction() {\n  return {\n    type: INCREMENT,\n  };\n}\nfunction decrementAction() {\n  return {\n    type: DECREMENT,\n  };\n}\n\nstore.dispatch(incrementAction());\nstore.dispatch(incrementAction());\nstore.dispatch(incrementAction());\nstore.dispatch(decrementAction());
\n
    \n
  • We are going to wrap entire React application with one Provider component, So when the store changes it re-render the whole application.
  • \n
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Redux","date":"2019-11-05T23:46:37.121Z","template":"post","draft":false,"slug":"Redux/","tags":["Redux","React","Programming Notes"],"category":"Programming","description":"Redux is a predictable state container for JavaScript apps.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Redux/"},{"id":"en/2019-11-06-Passing-custom-header-via-apollo-client.md","data":{"title":"Passing custom HTTP Header via Apollo Client","date":"2019-11-06T23:46:37.121Z","description":"Today I wanted to send along an array as a parameter with all queries from client to server. But I wanted to find a quick way to accomplish the task as changing all queries took a tremendous amount of time. One thing that came to my mind was making use of ...","template":"post","draft":false,"tags":["React","Apollo Client","C#","Programming Notes"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Today I wanted to send along an array as a parameter with all queries from client to server. But I wanted to find a quick way to accomplish the task as changing all queries took a tremendous amount of time. One thing that came to my mind was making use of Apollo Client by adding a custom header every time a request is sent to the server. `Apollo Link` is a state management library for our client-side dashboard. It comes with something called `Link` which is more like the concept of middleware but in a much more flexible and elegant way. The cool thing about this feature is that they are chainable so that we can snap together and define the functionality to handle GraphQL requests by the client. So when we issue a GraphQL request, every single link is applied one after another. So it's the best place to add the custom header:\n\n```js\nconst addOrigin = setContext(async (_, { headers }) => {\n const IDs = await localStorage.getItem(\"IDs\");\n return {\n headers: {\n ...headers,\n customHeaderName: IDs,\n },\n };\n});\n\nconst links = [, /* other links */ addOrigin, httpLink];\n\nexport const client = new ApolloClient({\n cache,\n link: ApolloLink.from(links),\n});\n```\n\nOn the backend we are using `graphql-dotnet` so all I had to do was to define a class and populate the header:\n\n```csharp\nservices.AddGraphQL()\n    .AddUserContextBuilder(context => new GraphQLUserContext { User = context.User, Headers = context.Request.Headers})\n    .AddGraphTypes(ServiceLifetime.Scoped);\n\npublic class GraphQLUserContext\n{\n    public IHeaderDictionary Headers { get; set; }\n}\n```\n\nThe code captures the headers and then make it available in resolve methods:\n\n```csharp\npublic class MyGraphType : ObjectGraphType\n{\n    public MyGraphType(MyService myService)\n    {\n        Field>(\n            \"items\",\n            resolve: context =>\n            {\n                var headers = (context.UserContext as dynamic).Headers as IHeaderDictionary;\n                var ids = headers?[\"customHeaderName\"];\n                if (string.IsNullOrEmpty(ids)) return myService.GetAllAsync();\n                var ids = (ids.Value).ToString().Split(\", \").Select(long.Parse);\n                return myService.GetAllAsync(ids);\n            });\n    }\n}\n\n```","filePath":"src/content/blog/en/2019-11-06-Passing-custom-header-via-apollo-client.md","assetImports":["./covers/cover.png"],"digest":"d8fc29060d6f1ae8","rendered":{"html":"

Today I wanted to send along an array as a parameter with all queries from client to server. But I wanted to find a quick way to accomplish the task as changing all queries took a tremendous amount of time. One thing that came to my mind was making use of Apollo Client by adding a custom header every time a request is sent to the server. Apollo Link is a state management library for our client-side dashboard. It comes with something called Link which is more like the concept of middleware but in a much more flexible and elegant way. The cool thing about this feature is that they are chainable so that we can snap together and define the functionality to handle GraphQL requests by the client. So when we issue a GraphQL request, every single link is applied one after another. So it’s the best place to add the custom header:

\n
const addOrigin = setContext(async (_, { headers }) => {\n  const IDs = await localStorage.getItem(\"IDs\");\n  return {\n    headers: {\n      ...headers,\n      customHeaderName: IDs,\n    },\n  };\n});\n\nconst links = [, /* other links */ addOrigin, httpLink];\n\nexport const client = new ApolloClient({\n  cache,\n  link: ApolloLink.from(links),\n});
\n

On the backend we are using graphql-dotnet so all I had to do was to define a class and populate the header:

\n
services.AddGraphQL()\n    .AddUserContextBuilder(context => new GraphQLUserContext { User = context.User, Headers = context.Request.Headers})\n    .AddGraphTypes(ServiceLifetime.Scoped);\n\npublic class GraphQLUserContext\n{\n    public IHeaderDictionary Headers { get; set; }\n}
\n

The code captures the headers and then make it available in resolve methods:

\n
public class MyGraphType : ObjectGraphType\n{\n    public MyGraphType(MyService myService)\n    {\n        Field<ListGraphType<MyType>>(\n            \"items\",\n            resolve: context =>\n            {\n                var headers = (context.UserContext as dynamic).Headers as IHeaderDictionary;\n                var ids = headers?[\"customHeaderName\"];\n                if (string.IsNullOrEmpty(ids)) return myService.GetAllAsync();\n                var ids = (ids.Value).ToString().Split(\", \").Select(long.Parse);\n                return myService.GetAllAsync(ids);\n            });\n    }\n}\n
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Passing custom HTTP Header via Apollo Client","date":"2019-11-06T23:46:37.121Z","template":"post","draft":false,"slug":"Passing-custom-HTTP-Header-via-Apollo-Client/","tags":["React","Apollo Client","C#","Programming Notes"],"category":"Programming","description":"Today I wanted to send along an array as a parameter with all queries from client to server. But I wanted to find a quick way to accomplish the task as changing all queries took a tremendous amount of time. One thing that came to my mind was making use of ...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Passing-custom-HTTP-Header-via-Apollo-Client/"},{"id":"en/2019-11-16-Setting-Up-Tailwind.md","data":{"title":"Setting Up Tailwind","date":"2019-11-16T23:46:37.121Z","description":"Tailwind is a utility-first CSS framework for rapidly building custom user interfaces.","template":"post","draft":false,"tags":["Tailwind","PostCSS","CSS","Programming Notes"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"# Setup\n\n1. Create a directory then:\n\n`npm init -y`\n\n2. Install these dependencies:\n\n`npm install tailwindcss postcss-cli autoprefixer`\n\n3. `npx tailwind init` (It creates an empty **tailwind.config.js** file in the project root):\n\n```\nmodule.exports = {\n theme: {\n extend: {}\n },\n variants: {},\n plugins: []\n}\n\n```\n\n4. Create a **postcss.config.js** in the root of the project:\n\n```\nmodule.exports = {\n plugins: [\n require(\"tailwindcss\"),\n require(\"autoprefixer\")\n ]\n};\n```\n\n5. Create a CSS file that runs through the above process: `css/tailwind.css`:\n\n```css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n```\n\n6. Create a script to process the CSS through our list of PostCSS plugins:\n\n```json\n\"scripts\": {\n \"build\": \"postcss css/tailwind.css -o public/build/tailwind.css\"\n},\n```\n\n7. Run the command: `npm run build`; A new CSS file is generated that has been processed through the PostCSS.\n\n8. Add an HTML file in `public/index.html` and use the tailwind classes:\n\n```html\n\n \n \n \n \n Tailwindcss\n \n \n \n

Hello World!

\n \n\n```\n\n[Tailwind CSS Intellisense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) for intelligent auto-completion in VS Code\n\n## Hover\n\n```html\nBook your escape\n```\n\n## Responsive design:\n\nOut of the box Tailwind ships with four default breakpoints:\n\n- `sm` which kicks in at 640\n- `md` which kicks in at 768\n- `lg` which kicks in at 1024\n- `xl` which kicks in at 1280\n\n```html\n
\n```\n\n## Composing Utilities with `@apply`:\n\nChange `tailwind.css` file:\n\n```css\n@tailwind base;\n@tailwind components;\n\n.btn {\n @apply inline-block bg-indigo-500 text-white px-5 py-3 rounded-lg shadow-lg uppercase tracking-wider font-semibold text-sm;\n}\n.btn:hover {\n @apply bg-indigo-400;\n}\n.btn:focus {\n @apply outline-none shadow-outline;\n}\n.btn:active {\n @apply bg-indigo-600;\n}\n@screen sm {\n .btn {\n @apply text-base;\n }\n}\n\n@tailwind utilities;\n```\n\n## Add watch script for CSS files:\n\n```json\n\"scripts\": {\n \"watch\": \"postcss css/tailwind.css -o public/build/tailwind.css --watch\"\n},\n```\n\n# Adding Tailwind to a React project\n\n1. `npx create-react-app tailwind`\n\n2. `cd tailwind`\n\n3. `npm install tailwindcss postcss-cli autoprefixer`\n\n4. `touch postcss.config.js`:\n\n```js\nmodule.exports = {\n plugins: [require(\"tailwindcss\"), require(\"autoprefixer\")],\n};\n```\n\n5. `touch tailwind.css`:\n\n```css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n```\n\n6. Add build script:\n\n```json\n\"scripts\": {\n \"build:css\": \"postcss ./tailwind.css -o src/css/style.css\",\n},\n```\n\n7. Update `public/index.html`:\n\n```js\n\n```\n\n8. Install `concurrently` for watching `tailwind.css` changes:\n\n```json\n\"scripts\": {\n \"dev\": \"concurrently \\\"yarn watch:css\\\" \\\"yarn start\\\"\",\n \"start\": \"react-scripts start\",\n \"build\": \"react-scripts build\",\n \"watch:css\": \"onchange 'tailwind.css' -- yarn build:css\",\n \"build:css\": \"postcss ./tailwind.css -o src/css/style.css\",\n \"test\": \"react-scripts test\",\n \"eject\": \"react-scripts eject\"\n },\n```","filePath":"src/content/blog/en/2019-11-16-Setting-Up-Tailwind.md","assetImports":["./covers/cover.png"],"digest":"e1c054051744fe8b","rendered":{"html":"

Setup

\n
    \n
  1. Create a directory then:
  2. \n
\n

npm init -y

\n
    \n
  1. Install these dependencies:
  2. \n
\n

npm install tailwindcss postcss-cli autoprefixer

\n
    \n
  1. npx tailwind init (It creates an empty tailwind.config.js file in the project root):
  2. \n
\n
module.exports = {\n  theme: {\n    extend: {}\n  },\n  variants: {},\n  plugins: []\n}\n
\n
    \n
  1. Create a postcss.config.js in the root of the project:
  2. \n
\n
module.exports = {\n  plugins: [\n      require(\"tailwindcss\"),\n      require(\"autoprefixer\")\n  ]\n};
\n
    \n
  1. Create a CSS file that runs through the above process: css/tailwind.css:
  2. \n
\n
@tailwind base;\n@tailwind components;\n@tailwind utilities;
\n
    \n
  1. Create a script to process the CSS through our list of PostCSS plugins:
  2. \n
\n
\"scripts\": {\n    \"build\": \"postcss css/tailwind.css -o public/build/tailwind.css\"\n},
\n
    \n
  1. \n

    Run the command: npm run build; A new CSS file is generated that has been processed through the PostCSS.

    \n
  2. \n
  3. \n

    Add an HTML file in public/index.html and use the tailwind classes:

    \n
  4. \n
\n
<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    <title>Tailwindcss</title>\n    <link rel=\"stylesheet\" href=\"./build/tailwind.css\" />\n  </head>\n  <body>\n    <h1 class=\"text-4xl font-bold text-center text-blue-400\">Hello World!</h1>\n  </body>\n</html>
\n

Tailwind CSS Intellisense for intelligent auto-completion in VS Code

\n

Hover

\n
<a class=\"bg-indigo-500 hover:bg-indigo-400\" href=\"#\">Book your escape</a>
\n

Responsive design:

\n

Out of the box Tailwind ships with four default breakpoints:

\n
    \n
  • sm which kicks in at 640
  • \n
  • md which kicks in at 768
  • \n
  • lg which kicks in at 1024
  • \n
  • xl which kicks in at 1280
  • \n
\n
<div class=\"mt-4 sm:mt-6 md:mt-4\"></div>
\n

Composing Utilities with @apply:

\n

Change tailwind.css file:

\n
@tailwind base;\n@tailwind components;\n\n.btn {\n  @apply inline-block bg-indigo-500 text-white px-5 py-3 rounded-lg shadow-lg uppercase tracking-wider font-semibold text-sm;\n}\n.btn:hover {\n  @apply bg-indigo-400;\n}\n.btn:focus {\n  @apply outline-none shadow-outline;\n}\n.btn:active {\n  @apply bg-indigo-600;\n}\n@screen sm {\n  .btn {\n    @apply text-base;\n  }\n}\n\n@tailwind utilities;
\n

Add watch script for CSS files:

\n
\"scripts\": {\n  \"watch\": \"postcss css/tailwind.css -o public/build/tailwind.css --watch\"\n},
\n

Adding Tailwind to a React project

\n
    \n
  1. \n

    npx create-react-app tailwind

    \n
  2. \n
  3. \n

    cd tailwind

    \n
  4. \n
  5. \n

    npm install tailwindcss postcss-cli autoprefixer

    \n
  6. \n
  7. \n

    touch postcss.config.js:

    \n
  8. \n
\n
module.exports = {\n  plugins: [require(\"tailwindcss\"), require(\"autoprefixer\")],\n};
\n
    \n
  1. touch tailwind.css:
  2. \n
\n
@tailwind base;\n@tailwind components;\n@tailwind utilities;
\n
    \n
  1. Add build script:
  2. \n
\n
\"scripts\": {\n    \"build:css\": \"postcss ./tailwind.css -o src/css/style.css\",\n},
\n
    \n
  1. Update public/index.html:
  2. \n
\n
<body class=\"w-full bg-purple-100\">
\n
    \n
  1. Install concurrently for watching tailwind.css changes:
  2. \n
\n
\"scripts\": {\n    \"dev\": \"concurrently \\\"yarn watch:css\\\" \\\"yarn start\\\"\",\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"watch:css\": \"onchange 'tailwind.css' -- yarn build:css\",\n    \"build:css\": \"postcss ./tailwind.css -o src/css/style.css\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\"\n  },
","metadata":{"headings":[{"depth":1,"slug":"setup","text":"Setup"},{"depth":2,"slug":"hover","text":"Hover"},{"depth":2,"slug":"responsive-design","text":"Responsive design:"},{"depth":2,"slug":"composing-utilities-with-apply","text":"Composing Utilities with @apply:"},{"depth":2,"slug":"add-watch-script-for-css-files","text":"Add watch script for CSS files:"},{"depth":1,"slug":"adding-tailwind-to-a-react-project","text":"Adding Tailwind to a React project"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Setting Up Tailwind","date":"2019-11-16T23:46:37.121Z","template":"post","draft":false,"slug":"Setting-Up-Tailwind/","tags":["Tailwind","PostCSS","CSS","Programming Notes"],"category":"Programming","description":"Tailwind is a utility-first CSS framework for rapidly building custom user interfaces.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Setting-Up-Tailwind/"},{"id":"en/2019-12-15-Server-Sent-Events-and-React.md","data":{"title":"Server-Sent Events and React","date":"2019-12-15T23:46:37.121Z","description":"Server Sents Events are realtime events sent from the server to the client. It's a way to subscribe to a data stream sent by a server. Basically, it is a long-running HTTP connection with a particular mime type.","template":"post","draft":false,"tags":["React","Realtime","ASP.NET Core","Node.js"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Server Sents Events are realtime events sent from the server to the client. It's a way to subscribe to a data stream sent by a server. Basically, it is a long-running HTTP connection with a particular mime type. Contrary to WebSocket, Server-Sent Events are unidirectional which clients subscribe to a channel and get data from the server. Updates for the data are pushed to the client in realtime as they occur, so the client doesn't need to initiate any requests. When using SSE, we should consider these:\n\n- Requests can be redirected HTTP 301(permanent) &\n 307(temporary)\n- Only UTF-8 decoding is supported, no binary data\n- Protocol supports multiple type of events, default is message\n- Clients always reconnect (no need to handle)\n- Server sends HTTP 204 No Content to stop reconnection\n- Limited amount of global connections per site\n\n## Server Implementation:\n\nImplementing it on the server is pretty easy. All we need to do is running an endless loop. Inside the loop, we should set the somespecial HTTP headers and push the data to the response every 2 seconds:\n\n```csharp\npublic void Configure(IApplicationBuilder app, IWebHostEnvironment env,\n ILogger loggerDebug, Datasource datasource)\n{\n app.UseCors(\"MyPolicy\");\n\n app.UseRouting();\n app.UseEndpoints(endpoints =>\n {\n endpoints.MapGet(\"/stream\", async context =>\n {\n var response = context.Response;\n response.Headers.Add(\"connection\", \"keep-alive\");\n response.Headers.Add(\"cach-control\", \"no-cache\");\n response.Headers.Add(\"content-type\", \"text/event-stream\");\n\n while (true)\n {\n await response.Body\n .WriteAsync(Encoding.UTF8.GetBytes($\"data: {JsonSerializer.Serialize(datasource.GetData())}\\n\\n\"));\n\n await response.Body.FlushAsync();\n await Task.Delay(2 * 1000);\n }\n\n });\n });\n}\n```\n\nHere's also a Node.js version of the server:\n\n```js\napp.get(\"/stream\", (req, res) => {\n res.set({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n\n // enabling CORS\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Headers\":\n \"Origin, X-Requested-With, Content-Type, Accept\",\n });\n\n setInterval(() => {\n res.write(`data: ${JSON.stringify(getData())}\\n\\n`);\n }, 2000);\n});\n```\n\nAs you can see, we are sending the data in a specific format:\n\n```\ndata: My message\\n\\n\n```\n\n## Frontend Implementation\n\nImplementing it on the client is fairly easy. All we need to do is making use of `EventSource` API, which is a standard interface to interact with the Server-Sent Events protocol. It basically opens a persistent connection to our HTTP server. The cool thing about the API is that it keeps the connection open until we call `EventSource.close()`:\n\n```ts\nimport React from \"react\";\n\nconst ProductList = () => {\n const [data, setData] = React.useState([] as any);\n\n const formatter = new Intl.NumberFormat(\"en-GB\", {\n style: \"currency\",\n currency: \"gbp\",\n });\n\n React.useEffect(() => {\n let eventSource = new EventSource(\"http://localhost:5000/stream\");\n eventSource.onmessage = (e) => updateProdutList(JSON.parse(e.data));\n }, []);\n\n const updateProdutList = (product: any) => {\n setData([...product]);\n };\n\n return (\n \n \n \n \n \n \n \n \n \n {data.map((p: any) => (\n \n \n \n \n \n ))}\n \n
IdTitlePrice
{p.Id}{p.Title}{formatter.format(p.Price)}
\n );\n};\n\nexport { ProductList };\n```\n\nHere we have passed in the SSE endpoint URL to the `EventSource` constructor. It then goes and establishes the communication channel between the React app and the server. Then we added `onmessage` event handler which is called when new data is received. `updateProdutList` is responsible for updating the state so once the data is received we update the state with the latest data. The process of subscribing to the endpoint happens once the `ProductList` component is mounted; that's why we used `useEffect` inside the component.\n\nNow we can test the application:\n\n\"Realtime","filePath":"src/content/blog/en/2019-12-15-Server-Sent-Events-and-React.md","assetImports":["./covers/cover.png"],"digest":"e6fc755e4197cabb","rendered":{"html":"

Server Sents Events are realtime events sent from the server to the client. It’s a way to subscribe to a data stream sent by a server. Basically, it is a long-running HTTP connection with a particular mime type. Contrary to WebSocket, Server-Sent Events are unidirectional which clients subscribe to a channel and get data from the server. Updates for the data are pushed to the client in realtime as they occur, so the client doesn’t need to initiate any requests. When using SSE, we should consider these:

\n
    \n
  • Requests can be redirected HTTP 301(permanent) &\n307(temporary)
  • \n
  • Only UTF-8 decoding is supported, no binary data
  • \n
  • Protocol supports multiple type of events, default is message
  • \n
  • Clients always reconnect (no need to handle)
  • \n
  • Server sends HTTP 204 No Content to stop reconnection
  • \n
  • Limited amount of global connections per site
  • \n
\n

Server Implementation:

\n

Implementing it on the server is pretty easy. All we need to do is running an endless loop. Inside the loop, we should set the somespecial HTTP headers and push the data to the response every 2 seconds:

\n
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,\n        ILogger<Startup> loggerDebug, Datasource datasource)\n{\n    app.UseCors(\"MyPolicy\");\n\n    app.UseRouting();\n    app.UseEndpoints(endpoints =>\n    {\n        endpoints.MapGet(\"/stream\", async context =>\n        {\n            var response = context.Response;\n            response.Headers.Add(\"connection\", \"keep-alive\");\n            response.Headers.Add(\"cach-control\", \"no-cache\");\n            response.Headers.Add(\"content-type\", \"text/event-stream\");\n\n            while (true)\n            {\n                await response.Body\n                    .WriteAsync(Encoding.UTF8.GetBytes($\"data: {JsonSerializer.Serialize(datasource.GetData())}\\n\\n\"));\n\n                await response.Body.FlushAsync();\n                await Task.Delay(2 * 1000);\n            }\n\n        });\n    });\n}
\n

Here’s also a Node.js version of the server:

\n
app.get(\"/stream\", (req, res) => {\n  res.set({\n    \"Content-Type\": \"text/event-stream\",\n    \"Cache-Control\": \"no-cache\",\n    Connection: \"keep-alive\",\n\n    // enabling CORS\n    \"Access-Control-Allow-Origin\": \"*\",\n    \"Access-Control-Allow-Headers\":\n      \"Origin, X-Requested-With, Content-Type, Accept\",\n  });\n\n  setInterval(() => {\n    res.write(`data: ${JSON.stringify(getData())}\\n\\n`);\n  }, 2000);\n});
\n

As you can see, we are sending the data in a specific format:

\n
data: My message\\n\\n
\n

Frontend Implementation

\n

Implementing it on the client is fairly easy. All we need to do is making use of EventSource API, which is a standard interface to interact with the Server-Sent Events protocol. It basically opens a persistent connection to our HTTP server. The cool thing about the API is that it keeps the connection open until we call EventSource.close():

\n
import React from \"react\";\n\nconst ProductList = () => {\n  const [data, setData] = React.useState([] as any);\n\n  const formatter = new Intl.NumberFormat(\"en-GB\", {\n    style: \"currency\",\n    currency: \"gbp\",\n  });\n\n  React.useEffect(() => {\n    let eventSource = new EventSource(\"http://localhost:5000/stream\");\n    eventSource.onmessage = (e) => updateProdutList(JSON.parse(e.data));\n  }, []);\n\n  const updateProdutList = (product: any) => {\n    setData([...product]);\n  };\n\n  return (\n    <table className=\"table table-hover\">\n      <thead className=\"thead-dark\">\n        <tr>\n          <th>Id</th>\n          <th>Title</th>\n          <th>Price</th>\n        </tr>\n      </thead>\n      <tbody>\n        {data.map((p: any) => (\n          <tr key={p.Id}>\n            <td>{p.Id}</td>\n            <td>{p.Title}</td>\n            <td>{formatter.format(p.Price)}</td>\n          </tr>\n        ))}\n      </tbody>\n    </table>\n  );\n};\n\nexport { ProductList };
\n

Here we have passed in the SSE endpoint URL to the EventSource constructor. It then goes and establishes the communication channel between the React app and the server. Then we added onmessage event handler which is called when new data is received. updateProdutList is responsible for updating the state so once the data is received we update the state with the latest data. The process of subscribing to the endpoint happens once the ProductList component is mounted; that’s why we used useEffect inside the component.

\n

Now we can test the application:

\n\"Realtime","metadata":{"headings":[{"depth":2,"slug":"server-implementation","text":"Server Implementation:"},{"depth":2,"slug":"frontend-implementation","text":"Frontend Implementation"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Server-Sent Events and React","date":"2019-12-15T23:46:37.121Z","template":"post","draft":false,"slug":" Server-Sent-Events-and-React/","tags":["React","Realtime","ASP.NET Core","Node.js"],"category":"Programming","description":"Server Sents Events are realtime events sent from the server to the client. It's a way to subscribe to a data stream sent by a server. Basically, it is a long-running HTTP connection with a particular mime type.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":" Server-Sent-Events-and-React/"},{"id":"en/2020-10-12-getting-started-with-sequelize.md","data":{"title":"Getting Started With Sequelize","date":"2020-10-12T23:46:37.121Z","description":"Sequelize is an Object Relational Mapper (ORM) which enables us to query and manipulate data stored in a relational database. There are several ORM for Node.js out there...","template":"post","draft":false,"tags":["Node.js","Sequelize"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Sequelize is an Object Relational Mapper (ORM) which enables us to query and manipulate data stored in a relational database. There are several ORM for Node.js out there. Sequelize is one of them and it's pretty popular. In this short tutorial we will have a quick look at Sequelize then we will write a simple Node.js application to connect to a MySQL database.\n\n## Setting up the project\n\nTo start off, head over to command line and type the following commands to initialise the project:\n\n```js\ntake sequelize_todo\nyarn init -y\nyarn add sequelize mysql2 dotenv ts-node typescript -D\n```\n\nNext, create a file called `dbConnection.ts` in the root of the project:\n\n```js\nimport { Sequelize } from \"sequelize\";\n\nconst sequelize = new Sequelize({\n dialect: \"mysql\",\n username: process.env.DATABASE_USERNAME,\n password: process.env.DATABASE_PASSWORD,\n database: process.env.DATABASE_NAME,\n port: +process.env.DATABASE_PORT || 3306,\n});\n\nexport const database = {\n sequelize,\n};\n```\n\nAs you can see we have constructed an object using `Sequelize` constructor. This class needs some options which are required to connect to our MySQL database (that's why we have set `dialect` to \"mysql\". You can changes that to connect to other relational databases like SQL server, ...). Then we exported the newly created object.\n\nNext, create an `index.ts` file in the root of the project:\n\n```js\nimport * as dotenv from \"dotenv\";\ndotenv.config();\nimport { database } from \"./dbConnection\";\n(async () => {\n await database.sequelize.sync();\n})();\n```\n\nThe first couple of lines are used to load `.env` file into `process.env`. This means that we will need to create another file in the root of the project to define our secret values:\n\n```js\nDATABASE_HOST = localhost;\nDATABASE_USERNAME = root;\nDATABASE_PASSWORD = PASSWORD;\nDATABASE_NAME = DBNAME;\nDATABASE_PORT = 3306;\n```\n\n**NOTE**: Make sure you gitignore the `.env` file before pushing the code into remote repository.\n\n## Creating your first entity\n\nNow we need to define our entity which is an abstraction that represents a table in your database. An entity is just a class that extends `Model`. So let's create a directory called `models` then create a file called `User.ts` inside that directory:\n\n```js\nimport * as Sequelize from \"sequelize\";\n\nclass User extends Sequelize.Model {\n username: string;\n createdAt: Date;\n}\nexport const InitUser = (sequelize: Sequelize.Sequelize) => {\n User.init(\n {\n username: Sequelize.DataTypes.STRING,\n createdAt: Sequelize.DataTypes.DATE,\n },\n {\n sequelize,\n tableName: \"Users\",\n }\n );\n};\n```\n\nTo define our entity and its properties (Columns) we need to have access to the `sequelize` object which we exported previously. So let's head over to the `dbConnection.ts` file and update the file by passing `sequelize` object to the `InitUser` (which we have just exported):\n\n```js\nexport const database = {\n sequelize,\n User: InitUser(sequelize),\n};\n```\n\nNow if you run the project `ts-node index.ts` you will get this error:\n\n```js\n(node:11377) UnhandledPromiseRejectionWarning: SequelizeConnectionError: Unknown database 'sequelize_sample'\n```\n\nIt's because Sequelize doesn't know how to created the database so it needs a database to start with. So let's create the schema in MySQL:\n\n```sql\nCREATE SCHEMA `sequelize_sample` ;\n```\n\nNow if you run the project one more time, Sequelize is able to create the table for you:\n\n```js\nExecuting (default): CREATE TABLE IF NOT EXISTS `Users` (`id` INTEGER NOT NULL auto_increment , `username` VARCHAR(255), `createdAt` DATETIME, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;\nExecuting (default): SHOW FULL COLUMNS FROM `Users`;\nExecuting (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Users' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='sequelize_sample' AND REFERENCED_TABLE_NAME IS NOT NULL;\nExecuting (default): ALTER TABLE `Users` CHANGE `username` `username` VARCHAR(255);\nExecuting (default): ALTER TABLE `Users` CHANGE `createdAt` `createdAt` DATETIME;\nExecuting (default): ALTER TABLE `Users` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;\nExecuting (default): SHOW INDEX FROM `Users` FROM `sequelize_sample`\n```\n\nIn the next blog post I will explain how to query and manipulate data. You can find the code here on GitHub. (https://github.com/SirwanAfifi/sequelize_sample)","filePath":"src/content/blog/en/2020-10-12-getting-started-with-sequelize.md","assetImports":["./covers/cover.png"],"digest":"40e2eada2b00fa76","rendered":{"html":"

Sequelize is an Object Relational Mapper (ORM) which enables us to query and manipulate data stored in a relational database. There are several ORM for Node.js out there. Sequelize is one of them and it’s pretty popular. In this short tutorial we will have a quick look at Sequelize then we will write a simple Node.js application to connect to a MySQL database.

\n

Setting up the project

\n

To start off, head over to command line and type the following commands to initialise the project:

\n
take sequelize_todo\nyarn init -y\nyarn add sequelize mysql2 dotenv ts-node typescript -D
\n

Next, create a file called dbConnection.ts in the root of the project:

\n
import { Sequelize } from \"sequelize\";\n\nconst sequelize = new Sequelize({\n  dialect: \"mysql\",\n  username: process.env.DATABASE_USERNAME,\n  password: process.env.DATABASE_PASSWORD,\n  database: process.env.DATABASE_NAME,\n  port: +process.env.DATABASE_PORT || 3306,\n});\n\nexport const database = {\n  sequelize,\n};
\n

As you can see we have constructed an object using Sequelize constructor. This class needs some options which are required to connect to our MySQL database (that’s why we have set dialect to “mysql”. You can changes that to connect to other relational databases like SQL server, …). Then we exported the newly created object.

\n

Next, create an index.ts file in the root of the project:

\n
import * as dotenv from \"dotenv\";\ndotenv.config();\nimport { database } from \"./dbConnection\";\n(async () => {\n  await database.sequelize.sync();\n})();
\n

The first couple of lines are used to load .env file into process.env. This means that we will need to create another file in the root of the project to define our secret values:

\n
DATABASE_HOST = localhost;\nDATABASE_USERNAME = root;\nDATABASE_PASSWORD = PASSWORD;\nDATABASE_NAME = DBNAME;\nDATABASE_PORT = 3306;
\n

NOTE: Make sure you gitignore the .env file before pushing the code into remote repository.

\n

Creating your first entity

\n

Now we need to define our entity which is an abstraction that represents a table in your database. An entity is just a class that extends Model. So let’s create a directory called models then create a file called User.ts inside that directory:

\n
import * as Sequelize from \"sequelize\";\n\nclass User extends Sequelize.Model {\n  username: string;\n  createdAt: Date;\n}\nexport const InitUser = (sequelize: Sequelize.Sequelize) => {\n  User.init(\n    {\n      username: Sequelize.DataTypes.STRING,\n      createdAt: Sequelize.DataTypes.DATE,\n    },\n    {\n      sequelize,\n      tableName: \"Users\",\n    }\n  );\n};
\n

To define our entity and its properties (Columns) we need to have access to the sequelize object which we exported previously. So let’s head over to the dbConnection.ts file and update the file by passing sequelize object to the InitUser (which we have just exported):

\n
export const database = {\n  sequelize,\n  User: InitUser(sequelize),\n};
\n

Now if you run the project ts-node index.ts you will get this error:

\n
(node:11377) UnhandledPromiseRejectionWarning: SequelizeConnectionError: Unknown database 'sequelize_sample'
\n

It’s because Sequelize doesn’t know how to created the database so it needs a database to start with. So let’s create the schema in MySQL:

\n
CREATE SCHEMA `sequelize_sample` ;
\n

Now if you run the project one more time, Sequelize is able to create the table for you:

\n
Executing (default): CREATE TABLE IF NOT EXISTS `Users` (`id` INTEGER NOT NULL auto_increment , `username` VARCHAR(255), `createdAt` DATETIME, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;\nExecuting (default): SHOW FULL COLUMNS FROM `Users`;\nExecuting (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Users' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='sequelize_sample' AND REFERENCED_TABLE_NAME IS NOT NULL;\nExecuting (default): ALTER TABLE `Users` CHANGE `username` `username` VARCHAR(255);\nExecuting (default): ALTER TABLE `Users` CHANGE `createdAt` `createdAt` DATETIME;\nExecuting (default): ALTER TABLE `Users` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;\nExecuting (default): SHOW INDEX FROM `Users` FROM `sequelize_sample`
\n

In the next blog post I will explain how to query and manipulate data. You can find the code here on GitHub. (https://github.com/SirwanAfifi/sequelize_sample)

","metadata":{"headings":[{"depth":2,"slug":"setting-up-the-project","text":"Setting up the project"},{"depth":2,"slug":"creating-your-first-entity","text":"Creating your first entity"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Getting Started With Sequelize","date":"2020-10-12T23:46:37.121Z","template":"post","draft":false,"slug":"getting-started-with-sequelize/","tags":["Node.js","Sequelize"],"category":"Programming","description":"Sequelize is an Object Relational Mapper (ORM) which enables us to query and manipulate data stored in a relational database. There are several ORM for Node.js out there...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"getting-started-with-sequelize/"},{"id":"en/2020-10-12-transforming-JSON-data-into-relational-table.md","data":{"title":"MySQL - Transforming JSON data into relational tables","date":"2020-10-24T23:46:37.121Z","description":"MySQL provides some built-in functions to work with JSON data. One of which is JSON_TABLE which maps JSON data into a temporary relational table.","template":"post","draft":false,"tags":["MySQL","SQL"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Given that you have a table called `Products` in your database, one of its columns is of type `JSON` which has product's metadata:\n\n```json\n[\n {\n \"id\": \"1\",\n \"name\": \"Lorem ipsum jacket\",\n \"price\": 12.45,\n \"discount\": 10,\n \"offerEnd\": \"October 5, 2020 12:11:00\",\n \"rating\": 4,\n \"saleCount\": 54,\n \"tag\": [\"fashion\", \"men\", \"jacket\", \"full sleeve\"],\n \"variation\": [\n {\n \"color\": \"white\",\n \"image\": \"/assets/img/product/fashion/1.jpg\",\n \"size\": [\n {\n \"name\": \"x\",\n \"stock\": 3\n },\n {\n \"name\": \"m\",\n \"stock\": 2\n },\n {\n \"name\": \"xl\",\n \"stock\": 5\n }\n ]\n },\n {\n \"color\": \"black\",\n \"image\": \"/assets/img/product/fashion/8.jpg\",\n \"size\": [\n {\n \"name\": \"x\",\n \"stock\": 4\n },\n {\n \"name\": \"m\",\n \"stock\": 7\n },\n {\n \"name\": \"xl\",\n \"stock\": 9\n },\n {\n \"name\": \"xxl\",\n \"stock\": 1\n }\n ]\n },\n ],\n \"image\": [\n \"/assets/img/product/fashion/1.jpg\",\n \"/assets/img/product/fashion/3.jpg\",\n ],\n \"shortDescription\": \"Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur.\",\n \"fullDescription\": \"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?\"\n },\n```\n\nMySQL provides some built-in functions to work with JSON data. One of which is `JSON_TABLE` which maps JSON data into a temporary relational table:\n\n```sql\nSELECT\n ANY_VALUE(jData.id) AS id,\n\t jData.name,\n\t GROUP_CONCAT(IFNULL(color, \"---\") SEPARATOR \"-\") AS colors,\n\t COUNT(color) AS numberOfColors,\n ANY_VALUE(jData.price) AS price,\n ANY_VALUE(IFNULL(STR_TO_DATE(jData.offerEnd, \"%M %d, %Y %H:%i:%s\"), \"---\")) AS offerEnd,\n ANY_VALUE(jData.rating) AS rating,\n ANY_VALUE(jData.saleCount) AS saleCount\nFROM Products,\n\tJSON_TABLE(\n\t\tdata,\n\t\t\"$[*]\"\n\t\tCOLUMNS (\n\t\t\tid INT PATH \"$.id\",\n\t\t\tname NVARCHAR(100) PATH \"$.name\",\n price DECIMAL(13, 2) PATH \"$.price\",\n tags TEXT PATH \"$.tag[*]\",\n NESTED PATH \"$.variation[*]\" COLUMNS (\n\t\t\t\tcolor TEXT PATH \"$.color\"\n ),\n rating INT PATH \"$.rating\",\n discount FLOAT PATH \"$.discount\",\n offerEnd TEXT PATH \"$.offerEnd\",\n\t\t\tsaleCount INT PATH \"$.saleCount\"\n\t\t)\n\t) AS jData\nGROUP BY jData.name\nORDER BY id\n```\n\nWhich returns the following result:\n\n\"json_table\"\n\n###\n\nYou can find more info on MySQL documentation:\nhttps://dev.mysql.com/doc/refman/8.0/en/json.html","filePath":"src/content/blog/en/2020-10-12-transforming-JSON-data-into-relational-table.md","assetImports":["./covers/cover.png"],"digest":"ba6468462780fa37","rendered":{"html":"

Given that you have a table called Products in your database, one of its columns is of type JSON which has product’s metadata:

\n
[\n  {\n    \"id\": \"1\",\n    \"name\": \"Lorem ipsum jacket\",\n    \"price\": 12.45,\n    \"discount\": 10,\n    \"offerEnd\": \"October 5, 2020 12:11:00\",\n    \"rating\": 4,\n    \"saleCount\": 54,\n    \"tag\": [\"fashion\", \"men\", \"jacket\", \"full sleeve\"],\n    \"variation\": [\n      {\n        \"color\": \"white\",\n        \"image\": \"/assets/img/product/fashion/1.jpg\",\n        \"size\": [\n          {\n            \"name\": \"x\",\n            \"stock\": 3\n          },\n          {\n            \"name\": \"m\",\n            \"stock\": 2\n          },\n          {\n            \"name\": \"xl\",\n            \"stock\": 5\n          }\n        ]\n      },\n      {\n        \"color\": \"black\",\n        \"image\": \"/assets/img/product/fashion/8.jpg\",\n        \"size\": [\n          {\n            \"name\": \"x\",\n            \"stock\": 4\n          },\n          {\n            \"name\": \"m\",\n            \"stock\": 7\n          },\n          {\n            \"name\": \"xl\",\n            \"stock\": 9\n          },\n          {\n            \"name\": \"xxl\",\n            \"stock\": 1\n          }\n        ]\n      },\n    ],\n    \"image\": [\n      \"/assets/img/product/fashion/1.jpg\",\n      \"/assets/img/product/fashion/3.jpg\",\n    ],\n    \"shortDescription\": \"Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur.\",\n    \"fullDescription\": \"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?\"\n  },
\n

MySQL provides some built-in functions to work with JSON data. One of which is JSON_TABLE which maps JSON data into a temporary relational table:

\n
SELECT\n      ANY_VALUE(jData.id) AS id,\n\t    jData.name,\n\t    GROUP_CONCAT(IFNULL(color, \"---\") SEPARATOR \"-\") AS colors,\n\t    COUNT(color) AS numberOfColors,\n      ANY_VALUE(jData.price) AS price,\n      ANY_VALUE(IFNULL(STR_TO_DATE(jData.offerEnd, \"%M %d, %Y %H:%i:%s\"), \"---\")) AS offerEnd,\n      ANY_VALUE(jData.rating) AS rating,\n      ANY_VALUE(jData.saleCount) AS saleCount\nFROM Products,\n\tJSON_TABLE(\n\t\tdata,\n\t\t\"$[*]\"\n\t\tCOLUMNS (\n\t\t\tid INT PATH \"$.id\",\n\t\t\tname NVARCHAR(100) PATH \"$.name\",\n            price DECIMAL(13, 2) PATH \"$.price\",\n            tags TEXT PATH \"$.tag[*]\",\n            NESTED PATH \"$.variation[*]\" COLUMNS (\n\t\t\t\tcolor TEXT PATH \"$.color\"\n            ),\n            rating INT PATH \"$.rating\",\n            discount FLOAT PATH \"$.discount\",\n            offerEnd TEXT PATH \"$.offerEnd\",\n\t\t\tsaleCount INT PATH \"$.saleCount\"\n\t\t)\n\t) AS jData\nGROUP BY jData.name\nORDER BY id
\n

Which returns the following result:

\n\"json_table\"\n

\n

You can find more info on MySQL documentation:\nhttps://dev.mysql.com/doc/refman/8.0/en/json.html

","metadata":{"headings":[{"depth":3,"slug":"","text":""}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"MySQL - Transforming JSON data into relational tables","date":"2020-10-24T23:46:37.121Z","template":"post","draft":false,"slug":"Transforming-JSON-data-into-relational-tables/","tags":["MySQL","SQL"],"category":"Programming","description":"MySQL provides some built-in functions to work with JSON data. One of which is JSON_TABLE which maps JSON data into a temporary relational table.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Transforming-JSON-data-into-relational-tables/"},{"id":"en/2020-01-05-MobX-with-React.md","data":{"title":"MobX with React and TypeScript","date":"2020-01-05T23:46:37.121Z","description":"MobX is one of the popular state management libraries. One of the great things about MobX is that we can store state in a simple data structure and allow the library to take care of keeping everything up to date.","template":"post","draft":false,"tags":["React","State Management","MobX"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"MobX is one of the popular state management libraries. One of the great things about MobX is that we can store state in a simple data structure and allow the library to take care of keeping everything up to date. The MobX API is pretty simple; in fact, it has these four simple building blocks at its core:\n\n- Observable\n- Actions\n- Computed\n- Reactions\n\n## Observable\n\nThe idea is that when the data changes, the observable object notifies the observers. To define a property as observable, all we need to do is to use `@observable` decorator:\n\n```js\nclass TodoStore {\n @observable todos: Todo[];\n}\n```\n\nNow When a new value is assigned to `todos` array, the notifications will fire, and all the associated observers will be notified.\n\n## Actions\n\nAction is a way to change an observable (update the state). To define an action, we decorate methods inside the store with `@action`:\n\n```js\n@action toggleTodo = (id: string) => {\n this.todos = this.todos.map(todo => {\n if (todo.id === id) {\n return {\n ...todo,\n completed: !todo.completed\n };\n }\n return todo;\n });\n};\n```\n\n## Computed\n\nComputed can be used to derive values from the existing state or other computed values:\n\n```js\n@computed get info() {\n return {\n total: this.todos.length,\n completed: this.todos.filter(todo => todo.completed).length,\n notCompleted: this.todos.filter(todo => !todo.completed).length\n };\n}\n```\n\n## Reactions\n\nReactions track observables from inside the store itself. In the example below if the action to set `todos` is called, then it runs the second argument.\n\n```\nclass TodoStore {\n constructor() {\n reaction(\n () => this.todos,\n _ => console.log(this.todos.length)\n );\n }\n```\n\n# Creating a Simple Todo App with MobX and React\n\nNow that we have talked about the main concepts, let's create a simple todo app using React, MobX and TypeScript:\n\n\"MobX\n\nSo go to the terminal, create a directory then CD into it then type in this command to scaffold a new React project:\n\n```js\nnpx create-react-app . --typescript\n```\n\nFor this project, I am using Bootstrap so let's add it as a dependency to the newly created project:\n\n```js\nyarn add bootstrap --save\n```\n\nNow go to `index.tsx` and import `bootstrap.css`:\n\n```js\nimport \"bootstrap/dist/css/bootstrap.css\";\n```\n\nNow we'll install the needed dependencies:\n\n```js\nyarn add mobx mobx-react-lite uuid @types/uuid --save\n```\n\nThe next thing we have to do is to set `experimentalDecorators` flag to true in `tsconfig.json` in order for the MobX decorators to compile properly:\n\n```json\n{\n \"compilerOptions\": {\n // other stuff...\n\n \"experimentalDecorators\": true\n }\n}\n```\n\nAfter all the above stuff is done, we have MobX ready to go. Now let's create a store inside the project `src/stores/TodoStore.ts`. Add the following code to it:\n\n```js\nimport { observable, action, computed, reaction } from \"mobx\";\nimport { createContext } from \"react\";\nimport uuidv4 from \"uuid/v4\";\n\nexport interface Todo {\n id?: string;\n title: string;\n completed: boolean;\n}\n\nclass TodoStore {\n constructor() {\n reaction(\n () => this.todos,\n (_) => console.log(this.todos.length)\n );\n }\n\n @observable todos: Todo[] = [\n { id: uuidv4(), title: \"Item #1\", completed: false },\n { id: uuidv4(), title: \"Item #2\", completed: false },\n { id: uuidv4(), title: \"Item #3\", completed: false },\n { id: uuidv4(), title: \"Item #4\", completed: false },\n { id: uuidv4(), title: \"Item #5\", completed: true },\n { id: uuidv4(), title: \"Item #6\", completed: false },\n ];\n\n @action addTodo = (todo: Todo) => {\n this.todos.push({ ...todo, id: uuidv4() });\n };\n\n @action toggleTodo = (id: string) => {\n this.todos = this.todos.map((todo) => {\n if (todo.id === id) {\n return {\n ...todo,\n completed: !todo.completed,\n };\n }\n return todo;\n });\n };\n\n @action removeTodo = (id: string) => {\n this.todos = this.todos.filter((todo) => todo.id !== id);\n };\n\n @computed get info() {\n return {\n total: this.todos.length,\n completed: this.todos.filter((todo) => todo.completed).length,\n notCompleted: this.todos.filter((todo) => !todo.completed).length,\n };\n }\n}\n\nexport default createContext(new TodoStore());\n```\n\nNow create a new folder called components in the `src` directory and add `TodoAdd.tsx` and `TodoList.tsx`.\n\n### TodoAdd\n\n```js\nimport React, { useContext, useState } from \"react\";\nimport TodoStore from \"../stores/TodoStore\";\nimport { observer } from \"mobx-react-lite\";\n\nconst AddTodo = () => {\n const [title, setTitle] = useState(\"\");\n const todoStore = useContext(TodoStore);\n const { addTodo, info } = todoStore;\n\n return (\n <>\n
\n
\n Total items:  \n {info.total}\n
\n
\n Finished items:  \n {info.completed}\n
\n
\n Unfinished items:  \n {info.notCompleted}\n
\n
\n
\n setTitle(e.target.value)}\n />\n
\n
\n {\n addTodo({\n title: title,\n completed: false,\n });\n setTitle(\"\");\n }}\n >\n Add Todo\n \n
\n \n );\n};\n\nexport default observer(AddTodo);\n```\n\n### TodoList\n\n```js\nimport React, { useContext } from \"react\";\nimport TodoStore from \"../stores/TodoStore\";\nimport { observer } from \"mobx-react-lite\";\n\nconst TodoList = () => {\n const todoStore = useContext(TodoStore);\n const { todos, toggleTodo, removeTodo } = todoStore;\n return (\n <>\n
\n \n \n \n \n \n \n \n \n \n {todos.map(todo => (\n \n \n \n \n \n ))}\n \n
TitleCompleted?Actions
{todo.title}{todo.completed ? \"✅\" : \"\"}\n toggleTodo(todo.id!)}\n >\n Toggle\n \n removeTodo(todo.id!)}\n >\n Remove\n \n
\n
\n \n );\n};\n\nexport default observer(TodoList);\n\n```\n\nBoth components use `observer` which is an [HOC](https://sirwan.info/archive/2019/09/22/Higher-Order-Components/) to make the components observers of our store. So any changes to any of the observable will cause the React components to re-render.\n\nThat’s it 🚀 You’re now up and going with MobX in your React application.\n\n[Here](https://github.com/SirwanAfifi/mobxwithts)'s the source for the project.","filePath":"src/content/blog/en/2020-01-05-MobX-with-React.md","assetImports":["./covers/cover.png"],"digest":"5fa791c3e0c2f346","rendered":{"html":"

MobX is one of the popular state management libraries. One of the great things about MobX is that we can store state in a simple data structure and allow the library to take care of keeping everything up to date. The MobX API is pretty simple; in fact, it has these four simple building blocks at its core:

\n
    \n
  • Observable
  • \n
  • Actions
  • \n
  • Computed
  • \n
  • Reactions
  • \n
\n

Observable

\n

The idea is that when the data changes, the observable object notifies the observers. To define a property as observable, all we need to do is to use @observable decorator:

\n
class TodoStore {\n  @observable todos: Todo[];\n}
\n

Now When a new value is assigned to todos array, the notifications will fire, and all the associated observers will be notified.

\n

Actions

\n

Action is a way to change an observable (update the state). To define an action, we decorate methods inside the store with @action:

\n
@action toggleTodo = (id: string) => {\n    this.todos = this.todos.map(todo => {\n      if (todo.id === id) {\n        return {\n          ...todo,\n          completed: !todo.completed\n        };\n      }\n      return todo;\n    });\n};
\n

Computed

\n

Computed can be used to derive values from the existing state or other computed values:

\n
@computed get info() {\n    return {\n      total: this.todos.length,\n      completed: this.todos.filter(todo => todo.completed).length,\n      notCompleted: this.todos.filter(todo => !todo.completed).length\n    };\n}
\n

Reactions

\n

Reactions track observables from inside the store itself. In the example below if the action to set todos is called, then it runs the second argument.

\n
class TodoStore {\n  constructor() {\n    reaction(\n      () => this.todos,\n      _ => console.log(this.todos.length)\n    );\n  }
\n

Creating a Simple Todo App with MobX and React

\n

Now that we have talked about the main concepts, let’s create a simple todo app using React, MobX and TypeScript:

\n\"MobX\n

So go to the terminal, create a directory then CD into it then type in this command to scaffold a new React project:

\n
npx create-react-app . --typescript
\n

For this project, I am using Bootstrap so let’s add it as a dependency to the newly created project:

\n
yarn add bootstrap --save
\n

Now go to index.tsx and import bootstrap.css:

\n
import \"bootstrap/dist/css/bootstrap.css\";
\n

Now we’ll install the needed dependencies:

\n
yarn add mobx mobx-react-lite uuid @types/uuid --save
\n

The next thing we have to do is to set experimentalDecorators flag to true in tsconfig.json in order for the MobX decorators to compile properly:

\n
{\n  \"compilerOptions\": {\n    // other stuff...\n\n    \"experimentalDecorators\": true\n  }\n}
\n

After all the above stuff is done, we have MobX ready to go. Now let’s create a store inside the project src/stores/TodoStore.ts. Add the following code to it:

\n
import { observable, action, computed, reaction } from \"mobx\";\nimport { createContext } from \"react\";\nimport uuidv4 from \"uuid/v4\";\n\nexport interface Todo {\n  id?: string;\n  title: string;\n  completed: boolean;\n}\n\nclass TodoStore {\n  constructor() {\n    reaction(\n      () => this.todos,\n      (_) => console.log(this.todos.length)\n    );\n  }\n\n  @observable todos: Todo[] = [\n    { id: uuidv4(), title: \"Item #1\", completed: false },\n    { id: uuidv4(), title: \"Item #2\", completed: false },\n    { id: uuidv4(), title: \"Item #3\", completed: false },\n    { id: uuidv4(), title: \"Item #4\", completed: false },\n    { id: uuidv4(), title: \"Item #5\", completed: true },\n    { id: uuidv4(), title: \"Item #6\", completed: false },\n  ];\n\n  @action addTodo = (todo: Todo) => {\n    this.todos.push({ ...todo, id: uuidv4() });\n  };\n\n  @action toggleTodo = (id: string) => {\n    this.todos = this.todos.map((todo) => {\n      if (todo.id === id) {\n        return {\n          ...todo,\n          completed: !todo.completed,\n        };\n      }\n      return todo;\n    });\n  };\n\n  @action removeTodo = (id: string) => {\n    this.todos = this.todos.filter((todo) => todo.id !== id);\n  };\n\n  @computed get info() {\n    return {\n      total: this.todos.length,\n      completed: this.todos.filter((todo) => todo.completed).length,\n      notCompleted: this.todos.filter((todo) => !todo.completed).length,\n    };\n  }\n}\n\nexport default createContext(new TodoStore());
\n

Now create a new folder called components in the src directory and add TodoAdd.tsx and TodoList.tsx.

\n

TodoAdd

\n
import React, { useContext, useState } from \"react\";\nimport TodoStore from \"../stores/TodoStore\";\nimport { observer } from \"mobx-react-lite\";\n\nconst AddTodo = () => {\n  const [title, setTitle] = useState(\"\");\n  const todoStore = useContext(TodoStore);\n  const { addTodo, info } = todoStore;\n\n  return (\n    <>\n      <div className=\"alert alert-primary\">\n        <div className=\"d-inline col-4\">\n          Total items: &nbsp;\n          <span className=\"badge badge-info\">{info.total}</span>\n        </div>\n        <div className=\"d-inline col-4\">\n          Finished items: &nbsp;\n          <span className=\"badge badge-info\">{info.completed}</span>\n        </div>\n        <div className=\"d-inline col-4\">\n          Unfinished items: &nbsp;\n          <span className=\"badge badge-info\">{info.notCompleted}</span>\n        </div>\n      </div>\n      <div className=\"form-group\">\n        <input\n          className=\"form-control\"\n          type=\"text\"\n          value={title}\n          placeholder=\"Todo title...\"\n          onChange={(e) => setTitle(e.target.value)}\n        />\n      </div>\n      <div className=\"form-group\">\n        <button\n          className=\"btn btn-primary\"\n          onClick={(_) => {\n            addTodo({\n              title: title,\n              completed: false,\n            });\n            setTitle(\"\");\n          }}\n        >\n          Add Todo\n        </button>\n      </div>\n    </>\n  );\n};\n\nexport default observer(AddTodo);
\n

TodoList

\n
import React, { useContext } from \"react\";\nimport TodoStore from \"../stores/TodoStore\";\nimport { observer } from \"mobx-react-lite\";\n\nconst TodoList = () => {\n  const todoStore = useContext(TodoStore);\n  const { todos, toggleTodo, removeTodo } = todoStore;\n  return (\n    <>\n      <div className=\"row\">\n        <table className=\"table table-hover\">\n          <thead className=\"thead-light\">\n            <tr>\n              <th>Title</th>\n              <th>Completed?</th>\n              <th>Actions</th>\n            </tr>\n          </thead>\n          <tbody>\n            {todos.map(todo => (\n              <tr key={todo.id}>\n                <td>{todo.title}</td>\n                <td>{todo.completed ? \"✅\" : \"\"}</td>\n                <td>\n                  <button\n                    className=\"btn btn-sm btn-info\"\n                    onClick={_ => toggleTodo(todo.id!)}\n                  >\n                    Toggle\n                  </button>\n                  <button\n                    className=\"btn btn-sm btn-danger\"\n                    onClick={_ => removeTodo(todo.id!)}\n                  >\n                    Remove\n                  </button>\n                </td>\n              </tr>\n            ))}\n          </tbody>\n        </table>\n      </div>\n    </>\n  );\n};\n\nexport default observer(TodoList);\n
\n

Both components use observer which is an HOC to make the components observers of our store. So any changes to any of the observable will cause the React components to re-render.

\n

That’s it 🚀 You’re now up and going with MobX in your React application.

\n

Here’s the source for the project.

","metadata":{"headings":[{"depth":2,"slug":"observable","text":"Observable"},{"depth":2,"slug":"actions","text":"Actions"},{"depth":2,"slug":"computed","text":"Computed"},{"depth":2,"slug":"reactions","text":"Reactions"},{"depth":1,"slug":"creating-a-simple-todo-app-with-mobx-and-react","text":"Creating a Simple Todo App with MobX and React"},{"depth":3,"slug":"todoadd","text":"TodoAdd"},{"depth":3,"slug":"todolist","text":"TodoList"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"MobX with React and TypeScript","date":"2020-01-05T23:46:37.121Z","template":"post","draft":false,"slug":"MobX-with-React-and-TypeScript/","tags":["React","State Management","MobX"],"category":"Programming","description":"MobX is one of the popular state management libraries. One of the great things about MobX is that we can store state in a simple data structure and allow the library to take care of keeping everything up to date.","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"MobX-with-React-and-TypeScript/"},{"id":"en/2020-03-08-WebSocket-and-React.md","data":{"title":"WebSocket and React","date":"2020-03-08T23:46:37.121Z","description":"WebSocket is a communication protocol. It's bidirectional in nature which means that either client or server can send data at any time. With WebSocket, we can build applications such as multiplayer games, ...","template":"post","draft":false,"tags":["React","Realtime","SignalR","ASP.NET Core","Node.js"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"WebSocket is a communication protocol. It's bidirectional in nature which means that either client or server can send data at any time. With WebSocket, we can build applications such as multiplayer games, chat apps, collaboration software that work on the open web. In this blog, I going to show you how to create a WebSocket server both in .NET Core and Node.js. I'll start with the Node.js version as it's a bit easier (boilerplate code for it is just 13 lines of code).\n\n## WebSocket Server (Node.js)\n\nTo create a WebSocket server in Node.js we need to install a third-party package called `socket.io` which is pretty popular. So follow these steps to create the server:\n\n```\nmkdir -p websocket/node && cd \"$_\"\nyarn init -y\nyarn add express socket.io\ntouch index.js\n```\n\nNow open `index.js` and add the following code:\n\n```js\nconst app = require(\"express\")();\nconst http = require(\"http\").createServer(app);\nconst io = require(\"socket.io\")(http);\n\nio.on(\"connection\", (socket) => {\n socket.on(\"message\", (message) => {\n socket.broadcast.emit(\"message\", message);\n });\n});\n\nhttp.listen(8080, () => {\n console.log(\"listening on *:8080\");\n});\n```\n\nAs you can see we have initialized a new instance of `socket.io` using `http`. Then we added an event listener for the `connection` event. This keeps listening to any incoming WebSocket connection so whenever a new WebSocket connection is established from the client, the callback is invoked. Inside the callback again we keep listening to the incoming request from the newly created connection, If the client emits an event called `message` we broadcast the data to other subscribers. That's it, the backend part is done. Now let's create a frontend for it.\n\n## WebSocket Client\n\nI don't want to explain the process of creating a React app as it's pretty easy to scaffold a React application using `create-react-app`. So let's assume that we have an existing application and want to add chat functionality to it. First, make sure you have installed `socket.io-client` package. I should also mention that I'm going to use Bootstrap for stylying the components. What we are going to build is this widget:\n\n\"Chat\"\n\nTo create such component I'll break it down into two separate components, one for each single message and the other for the chat widget. So let's go ahead and create them:\n\n### Message component\n\n```js\nimport React from \"react\";\nimport user from \"../Assets/user.png\";\nexport default ({ userName, message }) => {\n return (\n <>\n
\n \n
\n
{userName}
\n

{message}

\n
\n
\n
\n \n );\n};\n```\n\n### Chat component\n\n```js\nimport React, { useState, useEffect } from \"react\";\nimport \"./Chat.css\";\nimport Message from \"./Message\";\nimport socketIOClient from \"socket.io-client\";\nconst socket = socketIOClient(\"http://localhost:8080\");\n\nexport default () => {\n const [userName, setUserName] = useState(\"\");\n const [message, setMessage] = useState(\"\");\n const [messages, setMessages] = useState([]);\n\n useEffect(() => {\n const uName = prompt(\"Name?\");\n if (uName) {\n setUserName(uName);\n }\n }, []);\n\n socket.on(\"message\", (message) => {\n setMessages([...messages, message]);\n });\n\n return (\n
\n
\n
\n Chat\n
\n
\n {messages.map((msg, index) => (\n \n ))}\n
\n
\n
\n {\n setMessage(e.target.value);\n }}\n type=\"text\"\n className=\"form-control input-sm\"\n placeholder=\"Type your message here...\"\n />\n {\n const msg = {\n id: Math.random() * 10,\n message,\n userName: userName,\n };\n setMessages([...messages, msg]);\n setMessage(\"\");\n\n socket.emit(\"message\", msg);\n }}\n >\n Send\n \n
\n
\n
\n
\n );\n};\n```\n\nAs you can see we first imported `socket.io`. Then there are three parts to make it work. The first part is to connect to our WebSocket server:\n\n```js\nimport socketIOClient from \"socket.io-client\";\nconst socket = socketIOClient(\"http://localhost:8080\");\n```\n\nThe second part is to listen to incoming messages from the backend. As soon as there is a new message we save it into our local state:\n\n```js\nsocket.on(\"message\", (message) => {\n setMessages([...messages, message]);\n});\n```\n\nThe third part is when we click on `Send` button which is simply emitting a new message to the WebSocket server:\n\n```js\nsocket.emit(\"message\", msg);\n```\n\nThat's it. We just built a simple chat application in just a few minutes. Now let's create the same functionality using .NET Core.\n\n## WebSocket Server (.NET Core)\n\nTo create a WebSocket server in .NET Core we should use SignalR as it's incredibly simple yet powerful library to create real-time web applications. So let's type in the following commands to create a project:\n\n```\nmkdir -p websocket/dotnet && cd \"$_\"\ndotnet new web\n```\n\nNext we need something called `Hub` which is a class for listening and emitting data to subscribers. So let's create a Hub called `ChatHub`:\n\n```csharp\npublic class ChatHub : Hub\n{\n public async Task Message(MessageModel message)\n {\n await Clients.Others.SendAsync(\"message\", message);\n }\n}\n\npublic class MessageModel\n{\n public string UserName { get; set; }\n public string Message { get; set; }\n}\n```\n\nThen we will need to configure the server to respond to WebSocket requests. So let's change `Startup.cs` as the following:\n\n```csharp\npublic class Startup\n{\n public void ConfigureServices(IServiceCollection services)\n {\n services.AddCors(o => o.AddPolicy(\"CorsPolicy\", builder =>\n {\n builder\n .AllowAnyMethod()\n .AllowAnyHeader()\n .WithOrigins(\"http://localhost:3000\");\n }));\n services.AddSignalR();\n }\n public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n {\n app.UseCors(\"CorsPolicy\");\n\n\n app.UseRouting();\n app.UseEndpoints(endpoints =>\n {\n endpoints.MapHub(\"/chatHub\", options =>\n {\n options.Transports = HttpTransportType.WebSockets;\n });\n });\n }\n}\n```\n\nIt worth mentioning that SignalR includes some built-in transports to keep the underlying connection open. It means that it automatically chooses the most efficient transport type during an initial stage called negotiation. In the code, we have purposely set `WebSockets` transport by passing in a second argument to `MapHub` method. This is because the main focus of this blog post. But you can set other supported transports if you want to, If you don't explicitly set the transports, SignalR will use the most efficient type for you as mentioned. That's it. The server is now ready to communicate with the client. Unfortunately, the client part needs a couple of changes as the `socket.io-client` package doesn't support SignalR for its server as they are different in implementation. It means that we need to change the client code and the way it communicates with the server. First, we need to install an official Microsoft package:\n\n```\nyarn add @microsoft/signalr\n```\n\nSince the component structure is almost the same with one we had in `socket.io-client` so I'll just add the differences. First we need to import the SignalR package:\n\n```js\nimport {\n HubConnectionBuilder,\n LogLevel,\n HttpTransportType,\n} from \"@microsoft/signalr\";\n```\n\nThen we need to have a way to initialize and open the connection. We could do that by defining a `useEffect` hook:\n\n```js\nconst [connection, setConnection] = useState();\n\nuseEffect(\n configSocket();\n // as before\n}, []);\n\nconst configSocket = async () => {\n const socketConnection = new HubConnectionBuilder()\n .configureLogging(LogLevel.Debug)\n .withUrl(\"http://localhost:5000/chatHub\", {\n skipNegotiation: true,\n transport: HttpTransportType.WebSockets,\n })\n .build();\n await socketConnection.start();\n setConnection(socketConnection);\n}\n```\n\nWe only want to initialize `connection` when the component mounts that's why we provided an empty array as a second argument for the effect hook. Next we need to listen to any incoming message:\n\n```js\nconnection &&\n connection.on(\"message\", (message) => {\n setMessages([...messages, message]);\n });\n```\n\nAs the final step we need a way to emit the messages when a user clicks on `Send` button:\n\n```js\n {\n // as before\n\n connection && connection.invoke(\"message\", msg);\n }}\n>\n Send\n\n```\n\nThat's all we need to do to configure SignalR into our React application. Now you can run the project and see the result:\n\n\"Chat\"\n\n
\n\n**Note**: If you want to host the SignalR server on IIS you will have to enable WebSocket on IIS because it's not enabled by default. You can follow [this process](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-3.1#iisiis-express-support) to enable it:\n\n\"Enabling\n\n
\n\nSource code (https://github.com/SirwanAfifi/realtime)","filePath":"src/content/blog/en/2020-03-08-WebSocket-and-React.md","assetImports":["./covers/cover.png"],"digest":"af3c7e8a306c9bab","rendered":{"html":"

WebSocket is a communication protocol. It’s bidirectional in nature which means that either client or server can send data at any time. With WebSocket, we can build applications such as multiplayer games, chat apps, collaboration software that work on the open web. In this blog, I going to show you how to create a WebSocket server both in .NET Core and Node.js. I’ll start with the Node.js version as it’s a bit easier (boilerplate code for it is just 13 lines of code).

\n

WebSocket Server (Node.js)

\n

To create a WebSocket server in Node.js we need to install a third-party package called socket.io which is pretty popular. So follow these steps to create the server:

\n
mkdir -p websocket/node && cd \"$_\"\nyarn init -y\nyarn add express socket.io\ntouch index.js
\n

Now open index.js and add the following code:

\n
const app = require(\"express\")();\nconst http = require(\"http\").createServer(app);\nconst io = require(\"socket.io\")(http);\n\nio.on(\"connection\", (socket) => {\n  socket.on(\"message\", (message) => {\n    socket.broadcast.emit(\"message\", message);\n  });\n});\n\nhttp.listen(8080, () => {\n  console.log(\"listening on *:8080\");\n});
\n

As you can see we have initialized a new instance of socket.io using http. Then we added an event listener for the connection event. This keeps listening to any incoming WebSocket connection so whenever a new WebSocket connection is established from the client, the callback is invoked. Inside the callback again we keep listening to the incoming request from the newly created connection, If the client emits an event called message we broadcast the data to other subscribers. That’s it, the backend part is done. Now let’s create a frontend for it.

\n

WebSocket Client

\n

I don’t want to explain the process of creating a React app as it’s pretty easy to scaffold a React application using create-react-app. So let’s assume that we have an existing application and want to add chat functionality to it. First, make sure you have installed socket.io-client package. I should also mention that I’m going to use Bootstrap for stylying the components. What we are going to build is this widget:

\n\"Chat\"\n

To create such component I’ll break it down into two separate components, one for each single message and the other for the chat widget. So let’s go ahead and create them:

\n

Message component

\n
import React from \"react\";\nimport user from \"../Assets/user.png\";\nexport default ({ userName, message }) => {\n  return (\n    <>\n      <div className=\"media\">\n        <img\n          className=\"rounded-circle align-self-start mr-3\"\n          src={user}\n          alt=\"Avatar\"\n        />\n        <div className=\"media-body\">\n          <h5 className=\"mt-0\">{userName}</h5>\n          <p>{message}</p>\n        </div>\n      </div>\n      <div className=\"dropdown-divider\"></div>\n    </>\n  );\n};
\n

Chat component

\n
import React, { useState, useEffect } from \"react\";\nimport \"./Chat.css\";\nimport Message from \"./Message\";\nimport socketIOClient from \"socket.io-client\";\nconst socket = socketIOClient(\"http://localhost:8080\");\n\nexport default () => {\n  const [userName, setUserName] = useState(\"\");\n  const [message, setMessage] = useState(\"\");\n  const [messages, setMessages] = useState([]);\n\n  useEffect(() => {\n    const uName = prompt(\"Name?\");\n    if (uName) {\n      setUserName(uName);\n    }\n  }, []);\n\n  socket.on(\"message\", (message) => {\n    setMessages([...messages, message]);\n  });\n\n  return (\n    <div className=\"wrapper\">\n      <div className=\"card border-primary\">\n        <h5 className=\"card-header bg-primary text-white\">\n          <i className=\"fas fa-comment\"></i> Chat\n        </h5>\n        <div className=\"card-body overflow-auto\">\n          {messages.map((msg, index) => (\n            <Message\n              key={index}\n              userName={msg.userName}\n              message={msg.message}\n            />\n          ))}\n        </div>\n        <div className=\"card-footer border-primary p-0\">\n          <div className=\"input-group\">\n            <input\n              value={message}\n              onChange={(e) => {\n                setMessage(e.target.value);\n              }}\n              type=\"text\"\n              className=\"form-control input-sm\"\n              placeholder=\"Type your message here...\"\n            />\n            <button\n              className=\"btn btn-primary btn-sm\"\n              onClick={(_) => {\n                const msg = {\n                  id: Math.random() * 10,\n                  message,\n                  userName: userName,\n                };\n                setMessages([...messages, msg]);\n                setMessage(\"\");\n\n                socket.emit(\"message\", msg);\n              }}\n            >\n              Send\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};
\n

As you can see we first imported socket.io. Then there are three parts to make it work. The first part is to connect to our WebSocket server:

\n
import socketIOClient from \"socket.io-client\";\nconst socket = socketIOClient(\"http://localhost:8080\");
\n

The second part is to listen to incoming messages from the backend. As soon as there is a new message we save it into our local state:

\n
socket.on(\"message\", (message) => {\n  setMessages([...messages, message]);\n});
\n

The third part is when we click on Send button which is simply emitting a new message to the WebSocket server:

\n
socket.emit(\"message\", msg);
\n

That’s it. We just built a simple chat application in just a few minutes. Now let’s create the same functionality using .NET Core.

\n

WebSocket Server (.NET Core)

\n

To create a WebSocket server in .NET Core we should use SignalR as it’s incredibly simple yet powerful library to create real-time web applications. So let’s type in the following commands to create a project:

\n
mkdir -p websocket/dotnet && cd \"$_\"\ndotnet new web
\n

Next we need something called Hub which is a class for listening and emitting data to subscribers. So let’s create a Hub called ChatHub:

\n
public class ChatHub : Hub\n{\n    public async Task Message(MessageModel message)\n    {\n        await Clients.Others.SendAsync(\"message\", message);\n    }\n}\n\npublic class MessageModel\n{\n    public string UserName { get; set; }\n    public string Message { get; set; }\n}
\n

Then we will need to configure the server to respond to WebSocket requests. So let’s change Startup.cs as the following:

\n
public class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddCors(o => o.AddPolicy(\"CorsPolicy\", builder =>\n        {\n            builder\n            .AllowAnyMethod()\n            .AllowAnyHeader()\n            .WithOrigins(\"http://localhost:3000\");\n        }));\n        services.AddSignalR();\n    }\n    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n    {\n        app.UseCors(\"CorsPolicy\");\n\n\n        app.UseRouting();\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapHub<ChatHub>(\"/chatHub\", options =>\n            {\n                options.Transports = HttpTransportType.WebSockets;\n            });\n        });\n    }\n}
\n

It worth mentioning that SignalR includes some built-in transports to keep the underlying connection open. It means that it automatically chooses the most efficient transport type during an initial stage called negotiation. In the code, we have purposely set WebSockets transport by passing in a second argument to MapHub method. This is because the main focus of this blog post. But you can set other supported transports if you want to, If you don’t explicitly set the transports, SignalR will use the most efficient type for you as mentioned. That’s it. The server is now ready to communicate with the client. Unfortunately, the client part needs a couple of changes as the socket.io-client package doesn’t support SignalR for its server as they are different in implementation. It means that we need to change the client code and the way it communicates with the server. First, we need to install an official Microsoft package:

\n
yarn add @microsoft/signalr
\n

Since the component structure is almost the same with one we had in socket.io-client so I’ll just add the differences. First we need to import the SignalR package:

\n
import {\n  HubConnectionBuilder,\n  LogLevel,\n  HttpTransportType,\n} from \"@microsoft/signalr\";
\n

Then we need to have a way to initialize and open the connection. We could do that by defining a useEffect hook:

\n
const [connection, setConnection] = useState();\n\nuseEffect(\n  configSocket();\n  // as before\n}, []);\n\nconst configSocket = async () => {\n  const socketConnection = new HubConnectionBuilder()\n    .configureLogging(LogLevel.Debug)\n    .withUrl(\"http://localhost:5000/chatHub\", {\n      skipNegotiation: true,\n      transport: HttpTransportType.WebSockets,\n    })\n    .build();\n  await socketConnection.start();\n  setConnection(socketConnection);\n}
\n

We only want to initialize connection when the component mounts that’s why we provided an empty array as a second argument for the effect hook. Next we need to listen to any incoming message:

\n
connection &&\n  connection.on(\"message\", (message) => {\n    setMessages([...messages, message]);\n  });
\n

As the final step we need a way to emit the messages when a user clicks on Send button:

\n
<button\n  className=\"btn btn-primary btn-sm\"\n  onClick={(_) => {\n    // as before\n\n    connection && connection.invoke(\"message\", msg);\n  }}\n>\n  Send\n</button>
\n

That’s all we need to do to configure SignalR into our React application. Now you can run the project and see the result:

\n\"Chat\"\n
\n

Note: If you want to host the SignalR server on IIS you will have to enable WebSocket on IIS because it’s not enabled by default. You can follow this process to enable it:

\n\"Enabling\n
\n

Source code (https://github.com/SirwanAfifi/realtime)

","metadata":{"headings":[{"depth":2,"slug":"websocket-server-nodejs","text":"WebSocket Server (Node.js)"},{"depth":2,"slug":"websocket-client","text":"WebSocket Client"},{"depth":3,"slug":"message-component","text":"Message component"},{"depth":3,"slug":"chat-component","text":"Chat component"},{"depth":2,"slug":"websocket-server-net-core","text":"WebSocket Server (.NET Core)"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"WebSocket and React","date":"2020-03-08T23:46:37.121Z","template":"post","draft":false,"slug":"WebSocket-and-React/","tags":["React","Realtime","SignalR","ASP.NET Core","Node.js"],"category":"Programming","description":"WebSocket is a communication protocol. It's bidirectional in nature which means that either client or server can send data at any time. With WebSocket, we can build applications such as multiplayer games, ...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"WebSocket-and-React/"},{"id":"en/2021-07-20-Web-Server-Logging.md","data":{"title":"Web Server Logs","date":"2021-07-20T23:46:37.121Z","description":"An important part of managing software applications effectively is keeping logs, because they provide information about the server's performance and activity and can indicate any issues. An application's behavior has to be analyzed in order to track events and debug any issues...","template":"post","draft":false,"tags":["Web Server","Nginx","Logging"],"category":"Programming","lang":"en"},"body":"
\n \"Web\n
Photo by Clem Onojeghuo on Unsplash\n
\n
\n\nAn important part of managing software applications effectively is keeping logs, because they provide information about the server's performance and activity and can indicate any issues. An application's behavior has to be analyzed in order to track events and debug any issues.\nIn order to achieve this goal, I was given the task to implement logging into our applications. Our company has several applications, so adding an application log to them all wasn't a good idea. Although We have application level logs in some parts of our systems, but our goal was to centralize them so that we would have easy access to them. It could have been done with application code, but I would have had to change the codebases elsewheres. Hence, I decided to use our web server for the job. By default, Nginx provides out of the box logging which can be enabled with a few lines of code in the config file. `Error` and `Access` logs are the two types of logs in Nginx. Using the first one, you can track anything unexpected that happens. However, I was particularly interested in the second one, which logs all requests to the server as its name suggests. Nginx's logging functionality is enabled by default, so it does not require you to install third-party modules to make it available.\n\n```js\nevents {}\n\nhttp {\n server {\n listen 80;\n\n access_log /sites/files/log.txt;\n error_log /sites/files/error_log.txt;\n\n location / {\n return 200 \"Hello World!\";\n }\n }\n}\n```\n\nBy default, the format of the entry in the log file is as follows:\n\n```js\n172.17.0.1 - - [21/Jul/2021:07:24:53 +0000] \"GET / HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:03 +0000] \"GET / HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:05 +0000] \"GET /404.html HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:05 +0000] \"GET /favicon.ico HTTP/1.1\" 200 12 \"http://localhost:9091/404.html\" \"Mozilla/5.0....\"\n```\n\nAdditionally, we can disable logging for certain requests. For example, let's say we do not want to log the `/admin` request:\n\n```js\nlocation /admin {\n access_log off; // highlight-line\n return 200 \"Admin page\";\n}\n```\n\nOur logs should be stored slightly differently by adding more information to them, such as the full name of the user. We had a bit of a challenge to figure this out since the only way to determine who sent the request was by decoding the authorization token. Here is what we wanted in the log file:\n\n```js\nremote_address - user_full_name - URL(request_uri) - time_local - user_agent;\n```\n\nHowever, customizing the log is pretty simple, all we need to do is define the format:\n\n```js\nevents {}\n\nhttp {\n log_format custom '$remote_addr - user_full_name - URL($request_uri) - $time_local - $http_user_agent'; // highlight-line\n\n server {\n listen 80;\n\n access_log /sites/files/log.txt custom; // highlight-line\n error_log /sites/files/error_log.txt;\n\n location / {\n return 200 \"Hello World!\";\n }\n }\n}\n```\n\n`user_full_name` is the tricky part. The good news is that Nginx provides JavaScript support via `njs`. All we need to do is write our JavaScript logic (the syntax is limited to ECMAScript 5.1) inside a file and then invoke it from our configuration file. Within the function, we have access to `Request` and `Response` objects:\n\n```js\n// http.js\nfunction jwt(data) {\n var parts = data\n .split(\".\")\n .slice(0, 2)\n .map((v) => Buffer.from(v, \"base64url\").toString())\n .map(JSON.parse);\n return { headers: parts[0], payload: parts[1] };\n}\n\nfunction jwt_payload_user(request) {\n try {\n var auth = request.headersIn.Authorization;\n return jwt(auth.slice(7)).payload.profile.fulleName;\n } catch {\n return \"Anonymous\";\n }\n}\n\nexport default { jwt_payload_user };\n```\n\nWe can then import the above file into our Nginx configuration and use it:\n\n```js\nload_module modules/ngx_http_js_module.so; // highlight-line\n\nevents {}\n\nhttp {\n js_import /sites/files/http.js; // highlight-line\n js_set $user_full_name http.jwt_payload_user; // highlight-line\n\n log_format custom '$remote_addr - $user_full_name - URL($request_uri) - $time_local - $http_user_agent'; // highlight-line\n\n server {\n listen 80;\n\n access_log /sites/files/log.txt custom;\n error_log /sites/files/error_log.txt;\n\n location / {\n return 200 \"Hello World!\";\n }\n }\n}\n```","filePath":"src/content/blog/en/2021-07-20-Web-Server-Logging.md","digest":"3afd85170deff7c9","rendered":{"html":"
\n \"Web\n
Photo by Clem Onojeghuo on Unsplash\n
\n
\n

An important part of managing software applications effectively is keeping logs, because they provide information about the server’s performance and activity and can indicate any issues. An application’s behavior has to be analyzed in order to track events and debug any issues.\nIn order to achieve this goal, I was given the task to implement logging into our applications. Our company has several applications, so adding an application log to them all wasn’t a good idea. Although We have application level logs in some parts of our systems, but our goal was to centralize them so that we would have easy access to them. It could have been done with application code, but I would have had to change the codebases elsewheres. Hence, I decided to use our web server for the job. By default, Nginx provides out of the box logging which can be enabled with a few lines of code in the config file. Error and Access logs are the two types of logs in Nginx. Using the first one, you can track anything unexpected that happens. However, I was particularly interested in the second one, which logs all requests to the server as its name suggests. Nginx’s logging functionality is enabled by default, so it does not require you to install third-party modules to make it available.

\n
events {}\n\nhttp {\n  server {\n    listen 80;\n\n    access_log /sites/files/log.txt;\n    error_log /sites/files/error_log.txt;\n\n    location / {\n      return 200 \"Hello World!\";\n    }\n  }\n}
\n

By default, the format of the entry in the log file is as follows:

\n
172.17.0.1 - - [21/Jul/2021:07:24:53 +0000] \"GET / HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:03 +0000] \"GET / HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:05 +0000] \"GET /404.html HTTP/1.1\" 200 12 \"-\" \"Mozilla/5.0....\"\n172.17.0.1 - - [21/Jul/2021:07:25:05 +0000] \"GET /favicon.ico HTTP/1.1\" 200 12 \"http://localhost:9091/404.html\" \"Mozilla/5.0....\"
\n

Additionally, we can disable logging for certain requests. For example, let’s say we do not want to log the /admin request:

\n
location /admin {\n  access_log off; // highlight-line\n  return 200 \"Admin page\";\n}
\n

Our logs should be stored slightly differently by adding more information to them, such as the full name of the user. We had a bit of a challenge to figure this out since the only way to determine who sent the request was by decoding the authorization token. Here is what we wanted in the log file:

\n
remote_address - user_full_name - URL(request_uri) - time_local - user_agent;
\n

However, customizing the log is pretty simple, all we need to do is define the format:

\n
events {}\n\nhttp {\n  log_format custom '$remote_addr - user_full_name - URL($request_uri) - $time_local - $http_user_agent'; // highlight-line\n\n  server {\n    listen 80;\n\n    access_log /sites/files/log.txt custom; // highlight-line\n    error_log /sites/files/error_log.txt;\n\n    location / {\n      return 200 \"Hello World!\";\n    }\n  }\n}
\n

user_full_name is the tricky part. The good news is that Nginx provides JavaScript support via njs. All we need to do is write our JavaScript logic (the syntax is limited to ECMAScript 5.1) inside a file and then invoke it from our configuration file. Within the function, we have access to Request and Response objects:

\n
// http.js\nfunction jwt(data) {\n  var parts = data\n    .split(\".\")\n    .slice(0, 2)\n    .map((v) => Buffer.from(v, \"base64url\").toString())\n    .map(JSON.parse);\n  return { headers: parts[0], payload: parts[1] };\n}\n\nfunction jwt_payload_user(request) {\n  try {\n    var auth = request.headersIn.Authorization;\n    return jwt(auth.slice(7)).payload.profile.fulleName;\n  } catch {\n    return \"Anonymous\";\n  }\n}\n\nexport default { jwt_payload_user };
\n

We can then import the above file into our Nginx configuration and use it:

\n
load_module modules/ngx_http_js_module.so; // highlight-line\n\nevents {}\n\nhttp {\n  js_import /sites/files/http.js; // highlight-line\n  js_set $user_full_name http.jwt_payload_user; // highlight-line\n\n  log_format custom '$remote_addr - $user_full_name - URL($request_uri) - $time_local - $http_user_agent'; // highlight-line\n\n  server {\n    listen 80;\n\n    access_log /sites/files/log.txt custom;\n    error_log /sites/files/error_log.txt;\n\n    location / {\n      return 200 \"Hello World!\";\n    }\n  }\n}
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Web Server Logs","date":"2021-07-20T23:46:37.121Z","template":"post","draft":false,"slug":"web-server-logs","tags":["Web Server","Nginx","Logging"],"category":"Programming","description":"An important part of managing software applications effectively is keeping logs, because they provide information about the server's performance and activity and can indicate any issues. An application's behavior has to be analyzed in order to track events and debug any issues...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"web-server-logs"},{"id":"en/2022-05-05-blazor-meetup-reading.md","data":{"title":"Blazor Meetup","date":"2022-05-05T23:46:37.121Z","description":"On May 4, 2022, I attended a meetup at one of Microsoft's campuses in Reading. This was my first time at a meetup like this. It was about Blazor on .NET 6 presented by Steve Sanderson. I was already familiar with him from his previous work Knockout, which was/is an MVVM framework designed for the web. These days, I mostly build web applications using Node.js/React. In addition, I have been looking at Blazor...","template":"post","draft":false,"tags":["Blazor"],"category":"Programming","lang":"en"},"body":"\"ms_reading_blazor_features\"\n\nOn May 4, 2022, I attended a meetup at one of Microsoft's campuses in Reading. This was my first time at a meetup like this. It was about Blazor on .NET 6 presented by Steve Sanderson. I was already familiar with him from his previous work Knockout, which was/is an MVVM framework designed for the web. These days, I mostly build web applications using Node.js/React. In addition, I have been looking at Blazor. I believe that using it over React in .NET projects is a smart move because C# can be used on the client and the server. Therefore, there is no need to context switch between C# and JS/TS code all the time.\n\nDuring the event, Steve presented sample applications that illustrated some of Blazor's newest .NET 6 capabilities. He showed how we can build a full-stack application using Blazor in his demos. Here's some of the latest features:\n\n- Hot reload\n- Smaller download size\n- WebAssembly AOT\n- Native dependencies\n- Error boundaries\n- Dynamic component rendering\n- Render components from JS\n\nThe last one was my personal favourite. Steve demonstrated how to use a Blazor component within a React application.\n\n \"ms_reading_react\"","filePath":"src/content/blog/en/2022-05-05-blazor-meetup-reading.md","digest":"06a4d15aecb34647","rendered":{"html":"\"ms_reading_blazor_features\"\n

On May 4, 2022, I attended a meetup at one of Microsoft’s campuses in Reading. This was my first time at a meetup like this. It was about Blazor on .NET 6 presented by Steve Sanderson. I was already familiar with him from his previous work Knockout, which was/is an MVVM framework designed for the web. These days, I mostly build web applications using Node.js/React. In addition, I have been looking at Blazor. I believe that using it over React in .NET projects is a smart move because C# can be used on the client and the server. Therefore, there is no need to context switch between C# and JS/TS code all the time.

\n

During the event, Steve presented sample applications that illustrated some of Blazor’s newest .NET 6 capabilities. He showed how we can build a full-stack application using Blazor in his demos. Here’s some of the latest features:

\n
    \n
  • Hot reload
  • \n
  • Smaller download size
  • \n
  • WebAssembly AOT
  • \n
  • Native dependencies
  • \n
  • Error boundaries
  • \n
  • Dynamic component rendering
  • \n
  • Render components from JS
  • \n
\n

The last one was my personal favourite. Steve demonstrated how to use a Blazor component within a React application.

\n \"ms_reading_react\"","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Blazor Meetup","date":"2022-05-05T23:46:37.121Z","template":"post","draft":false,"slug":"blazor-meetup-reading","tags":["Blazor"],"category":"Programming","description":"On May 4, 2022, I attended a meetup at one of Microsoft's campuses in Reading. This was my first time at a meetup like this. It was about Blazor on .NET 6 presented by Steve Sanderson. I was already familiar with him from his previous work Knockout, which was/is an MVVM framework designed for the web. These days, I mostly build web applications using Node.js/React. In addition, I have been looking at Blazor...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"blazor-meetup-reading"},{"id":"en/2020-01-25-Displaying-Secured-Images.md","data":{"title":"Displaying Secured Images","date":"2020-01-25T23:46:37.121Z","description":"Ran into an interesting problem this week with displaying secured images on the page. The problem is that `img` tag doesn't show the image if the resource is secured with a token or a username/password...","template":"post","draft":false,"tags":["Node.js","Express","React","JavaScript"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"Ran into an interesting problem this week with displaying secured images on the page. The problem is that `img` tag doesn't show the image if the resource is secured with a token or a username/password. When the browser encounters an image tag with a secured URL, it's unable to show the image, so it immediately responds with 401 Unauthorized error because the request is heading towards a protected resource. To show the problem, consider the following endpoint which requires the caller to pass in a token:\n\n```js\n// server.js\napp.get(\"/downloadSecuredImage\", authentication, (req, res) => {\n res.sendFile(`${__dirname}/images/Me.jpg`);\n});\n```\n\nAs you can see, the Express framework provides a `sendFile()` method available on the response object which can be used to send static files to the client. It automatically sets appropriate headers to the response. I should also mention the token validation takes place using a custom Express middleware:\n\n```js\nconst jwt = require(\"jsonwebtoken\");\nconst database = require(\"../db/users\");\n\nconst authentication = async (req, res, next) => {\n try {\n const token = req.header(\"Authorization\").replace(\"Bearer \", \"\");\n const decoded = await jwt.verify(token, \"SUPER_SECRET_PRIVATE_KEY\");\n const user = database.users.some((u) => u.email === decoded.user);\n if (!user) {\n throw new Error(\"Invalid credentials\");\n }\n req.user = decoded.user;\n next();\n } catch (exception) {\n console.log(exception);\n res.status(401).send(exception);\n }\n};\n\nmodule.exports = authentication;\n```\n\nNow if we want an `img` tag to point to that endpoint, we get `401 Unauthorized` error, and the result would be the following image:\n\n\"secured-image\"\n\nOne solution to tackle this issue is by embedding the image using a particular format. This format is called Data URL, and we can use it inside the image's `src` attribute, So the browser does not have to make another request to get it. Here is an example of how such Data URL looks like:\n\n```\ndata:image/png;base64,R0lGODlhEAAQAM...\n```\n\nSo we'll need to issue a request of type blob (`responseType: \"blob\"`) to the protected endpoint with the JWT token provided directly from the code. This way, we don't need to hard-code the URL inside `src` attribute anymore. Once the request is completed, we then assign the response data to a variable and make use of `FileReader`'s `readAsDataUrl` method to convert the blob result to Base64-encoded string. Here is a React component doing the process:\n\n```tsx\nimport React, { useState } from \"react\";\nimport axios from \"axios\";\n\nexport default () => {\n const [token, setToken] = useState(\"\");\n const [image, setImage] = useState(\"\");\n\n const downloadImage = async () => {\n const img = await axios(`http://localhost:4000/downloadSecuredImage`, {\n responseType: \"blob\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n const blob = img.data;\n let reader = new FileReader();\n reader.readAsDataURL(blob);\n reader.onload = () => {\n console.log(reader.result);\n setImage(reader.result);\n };\n };\n\n return (\n
\n
\n
\n
\n downloadImage()}\n disabled={!token}\n >\n Download Image\n \n
\n
\n
\n
\n
\n \n
\n
\n {image && \"Image\"}\n
\n
\n
\n );\n};\n```\n\nNow when the button is clicked we get the file from the server and save the converted result into a state, When the browser encounters the data URL (the value of `image`), It decodes the data and constructs the original file. This way, we have embedded the image data directly into the document.\n\n\"SecureImageDemo\"","filePath":"src/content/blog/en/2020-01-25-Displaying-Secured-Images.md","assetImports":["./covers/cover.png"],"digest":"02d66a95c75f140d","rendered":{"html":"

Ran into an interesting problem this week with displaying secured images on the page. The problem is that img tag doesn’t show the image if the resource is secured with a token or a username/password. When the browser encounters an image tag with a secured URL, it’s unable to show the image, so it immediately responds with 401 Unauthorized error because the request is heading towards a protected resource. To show the problem, consider the following endpoint which requires the caller to pass in a token:

\n
// server.js\napp.get(\"/downloadSecuredImage\", authentication, (req, res) => {\n  res.sendFile(`${__dirname}/images/Me.jpg`);\n});
\n

As you can see, the Express framework provides a sendFile() method available on the response object which can be used to send static files to the client. It automatically sets appropriate headers to the response. I should also mention the token validation takes place using a custom Express middleware:

\n
const jwt = require(\"jsonwebtoken\");\nconst database = require(\"../db/users\");\n\nconst authentication = async (req, res, next) => {\n  try {\n    const token = req.header(\"Authorization\").replace(\"Bearer \", \"\");\n    const decoded = await jwt.verify(token, \"SUPER_SECRET_PRIVATE_KEY\");\n    const user = database.users.some((u) => u.email === decoded.user);\n    if (!user) {\n      throw new Error(\"Invalid credentials\");\n    }\n    req.user = decoded.user;\n    next();\n  } catch (exception) {\n    console.log(exception);\n    res.status(401).send(exception);\n  }\n};\n\nmodule.exports = authentication;
\n

Now if we want an img tag to point to that endpoint, we get 401 Unauthorized error, and the result would be the following image:

\n\"secured-image\"\n

One solution to tackle this issue is by embedding the image using a particular format. This format is called Data URL, and we can use it inside the image’s src attribute, So the browser does not have to make another request to get it. Here is an example of how such Data URL looks like:

\n
data:image/png;base64,R0lGODlhEAAQAM...
\n

So we’ll need to issue a request of type blob (responseType: \"blob\") to the protected endpoint with the JWT token provided directly from the code. This way, we don’t need to hard-code the URL inside src attribute anymore. Once the request is completed, we then assign the response data to a variable and make use of FileReader’s readAsDataUrl method to convert the blob result to Base64-encoded string. Here is a React component doing the process:

\n
import React, { useState } from \"react\";\nimport axios from \"axios\";\n\nexport default () => {\n  const [token, setToken] = useState(\"\");\n  const [image, setImage] = useState<string | ArrayBuffer | null>(\"\");\n\n  const downloadImage = async () => {\n    const img = await axios(`http://localhost:4000/downloadSecuredImage`, {\n      responseType: \"blob\",\n      headers: {\n        Authorization: `Bearer ${token}`,\n      },\n    });\n    const blob = img.data;\n    let reader = new FileReader();\n    reader.readAsDataURL(blob);\n    reader.onload = () => {\n      console.log(reader.result);\n      setImage(reader.result);\n    };\n  };\n\n  return (\n    <div className=\"container\">\n      <div className=\"row\">\n        <div className=\"col\">\n          <div className=\"form-group\">\n            <button\n              className=\"btn btn-info\"\n              onClick={(_) => downloadImage()}\n              disabled={!token}\n            >\n              Download Image\n            </button>\n          </div>\n        </div>\n      </div>\n      <div className=\"row\">\n        <div className=\"col\">\n          <img\n            src=\"http://localhost:4000/downloadSecuredImage\"\n            alt=\"This is a secured image....\"\n          />\n        </div>\n        <div className=\"col\">\n          {image && <img src={image as string} alt=\"Image\" />}\n        </div>\n      </div>\n    </div>\n  );\n};
\n

Now when the button is clicked we get the file from the server and save the converted result into a state, When the browser encounters the data URL (the value of image), It decodes the data and constructs the original file. This way, we have embedded the image data directly into the document.

\n\"SecureImageDemo\"","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Displaying Secured Images","date":"2020-01-25T23:46:37.121Z","template":"post","draft":false,"slug":"Displaying-Secured-Images/","tags":["Node.js","Express","React","JavaScript"],"category":"Programming","description":"Ran into an interesting problem this week with displaying secured images on the page. The problem is that `img` tag doesn't show the image if the resource is secured with a token or a username/password...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"Displaying-Secured-Images/"},{"id":"en/2021-07-25-using-mirage-with-vite.md","data":{"title":"Using Mirage With Vite","date":"2021-07-25T23:46:37.121Z","description":"Recently, I have been using Vite and liked it quite a bit. It's an extremely fast build tool, If you haven't checked it out, you should definitely do so. Although it was developed by Evan You, it can be used for React, Svelte, and more...","template":"post","draft":false,"tags":["React","Mirage","Vite"],"category":"Programming","lang":"en"},"body":"Recently, I have been using Vite and liked it quite a bit. It's an extremely fast build tool, If you haven't checked it out, you should definitely do so. Although it was developed by Evan You, it can be used for React, Svelte, and more:\n\n- `vanilla`\n- `vanilla-ts`\n- `vue`\n- `vue-ts`\n- `react`\n- `react-ts`\n- `preact`\n- `preact-ts`\n- `lit-element`\n- `lit-element-ts`\n- `svelte`\n- `svelte-ts`\n\nAnother excellent tool that I'm going to talk about in this post is Mirage, which is designed to mock APIs. I wanted to use both of these tools in one of my projects. My previous experience with Mirage was with CRA. But as it was the first time I tried using it in Vite, I decided to give it a go.\n\nWith the following steps, you can scaffold a React app quickly:\n\n- `yarn create vite`:\n\n```js\n✔ Project name: > mirage_vite\n✔ Select a framework: › react\n✔ Select a variant: › react-ts\n```\n\n- `cd mirage_vite`\n- `yarn add @types/node`\n- `yarn`\n- `yarn dev`\n\n \"Hello\n\nThe next step is to install Mirage:\n\n- `yarn add miragejs -D`\n\nOnce it is installed, you will need to make the following modifications to your `main.tsx` file:\n\n```ts\n// React imports...\nimport { createServer } from \"miragejs\"; // highlight-line\nimport { getTodos } from \"./api/todos\";\n\n// highlight-start\nconst environment = process.env.NODE_ENV;\nif (environment !== \"production\") {\n createServer({\n routes() {\n this.get(\"/api/todos\", () => ({\n todos: [\n {\n userId: 1,\n id: 1,\n title: \"delectus aut autem\",\n completed: false,\n },\n ],\n }));\n },\n });\n}\n// highlight-end\n\nReactDOM.render(\n \n \n ,\n document.getElementById(\"root\")\n);\n```\n\nWith the fake API now ready, you can use it in your components:\n\n```tsx\nimport React, { useEffect, useState } from \"react\";\n\ninterface Todo {\n userId: number;\n id: number;\n title: string;\n completed: boolean;\n}\n\nfunction App() {\n const [todos, setTodos] = useState([]);\n useEffect(() => {\n fetch(\"/api/todos\")\n .then((res) => res.json())\n .then((dt) => setTodos(dt.todos));\n }, []);\n\n return (\n
\n
    \n {todos.map((todo) => (\n
  • {todo.title}
  • \n ))}\n
\n
\n );\n}\n\nexport default App;\n```","filePath":"src/content/blog/en/2021-07-25-using-mirage-with-vite.md","digest":"07f0be5b2544368f","rendered":{"html":"

Recently, I have been using Vite and liked it quite a bit. It’s an extremely fast build tool, If you haven’t checked it out, you should definitely do so. Although it was developed by Evan You, it can be used for React, Svelte, and more:

\n
    \n
  • vanilla
  • \n
  • vanilla-ts
  • \n
  • vue
  • \n
  • vue-ts
  • \n
  • react
  • \n
  • react-ts
  • \n
  • preact
  • \n
  • preact-ts
  • \n
  • lit-element
  • \n
  • lit-element-ts
  • \n
  • svelte
  • \n
  • svelte-ts
  • \n
\n

Another excellent tool that I’m going to talk about in this post is Mirage, which is designed to mock APIs. I wanted to use both of these tools in one of my projects. My previous experience with Mirage was with CRA. But as it was the first time I tried using it in Vite, I decided to give it a go.

\n

With the following steps, you can scaffold a React app quickly:

\n
    \n
  • yarn create vite:
  • \n
\n
✔ Project name: > mirage_vite\n✔ Select a framework: › react\n✔ Select a variant: › react-ts
\n
    \n
  • cd mirage_vite
  • \n
  • yarn add @types/node
  • \n
  • yarn
  • \n
  • yarn dev
  • \n
\n \"Hello\n

The next step is to install Mirage:

\n
    \n
  • yarn add miragejs -D
  • \n
\n

Once it is installed, you will need to make the following modifications to your main.tsx file:

\n
// React imports...\nimport { createServer } from \"miragejs\"; // highlight-line\nimport { getTodos } from \"./api/todos\";\n\n// highlight-start\nconst environment = process.env.NODE_ENV;\nif (environment !== \"production\") {\n  createServer({\n    routes() {\n      this.get(\"/api/todos\", () => ({\n        todos: [\n          {\n            userId: 1,\n            id: 1,\n            title: \"delectus aut autem\",\n            completed: false,\n          },\n        ],\n      }));\n    },\n  });\n}\n// highlight-end\n\nReactDOM.render(\n  <React.StrictMode>\n    <App />\n  </React.StrictMode>,\n  document.getElementById(\"root\")\n);
\n

With the fake API now ready, you can use it in your components:

\n
import React, { useEffect, useState } from \"react\";\n\ninterface Todo {\n  userId: number;\n  id: number;\n  title: string;\n  completed: boolean;\n}\n\nfunction App() {\n  const [todos, setTodos] = useState<Todo[]>([]);\n  useEffect(() => {\n    fetch(\"/api/todos\")\n      .then((res) => res.json())\n      .then((dt) => setTodos(dt.todos));\n  }, []);\n\n  return (\n    <div className=\"App\">\n      <ul>\n        {todos.map((todo) => (\n          <li key={todo.id}>{todo.title}</li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n\nexport default App;
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Using Mirage With Vite","date":"2021-07-25T23:46:37.121Z","template":"post","draft":false,"slug":"using-mirage-with-vite","tags":["React","Mirage","Vite"],"category":"Programming","description":"Recently, I have been using Vite and liked it quite a bit. It's an extremely fast build tool, If you haven't checked it out, you should definitely do so. Although it was developed by Evan You, it can be used for React, Svelte, and more...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"using-mirage-with-vite"},{"id":"en/2021-09-01-showing-topbar-progress-indicator-in-react.md","data":{"title":"Showing Topbar Progress Indicator in React","date":"2021-09-01T23:46:37.121Z","description":"I use circular loading indicators in my React applications before data is returned from the server...","template":"post","draft":false,"tags":["React","React Query","Axios","Vite"],"category":"Programming","lang":"en"},"body":"I use circular loading indicators in my React applications before data is returned from the server:\n\n \"circular_loading\"\n\nWhich is a simple SVG file loaded as a React component:\n\n```tsx\n// other imports\nimport { ReactComponent as Circular } from \"./assets/CircularLoading.svg\";// highlight-line\n\nfunction App() {\n const { data, isLoading } = useQuery(\"users\", () => getUsers(), {})\n return (\n
\n {isLoading && // highlight-line}\n {data && (\n \n \n \n \n \n \n \n \n \n {data.map(user => (\n \n \n \n \n ))}\n \n
IDNameEmail
{user.name}{user.email}
\n )}\n
\n )\n}\n\nexport default App\n```\n\nIn one of our projects I was asked to add a topbar loading indicator:\n\n \"linear_loading\"\n\nSince it's an SVG file, it's pretty easy to do. However, it should be based on the elapsed time. As opposed to the first one, which spins as long as `isLoading` is set to `true`, for this one we will have to calculate the actual elapsed time and convert it to percentage, then use it as `width` for the loading indicator.\n\n```tsx\nfunction App() {\n const [progress, setProgress] = useState(0) // highlight-line\n const { data, isLoading } = useQuery(\n \"users\",\n () =>\n // highlight-start\n getUsers(progressEvent => {\n let percentCompleted = Math.floor(\n (progressEvent.loaded / progressEvent.total) * 100\n )\n setProgress(percentCompleted)\n }),\n // highlight-end\n {}\n )\n return (\n
\n {isLoading && // highlight-line}\n {isLoading && }\n {data && (\n \n \n \n \n \n \n \n \n \n {data.map(user => (\n \n \n \n \n \n ))}\n \n
IDNameEmail
{user.id}{user.name}{user.email}
\n )}\n
\n )\n}\n\n// highlight-start\nconst TopbarLoading = styled(Linear)<{ value?: number }>`\n #progress rect {\n transition: width 0.5s;\n width: ${props => (props.value && `${props.value}px`) || \"unset\"};\n }\n`\n// highlight-end\n\nexport default App\n```\n\nYou can see from the code above that we changed the service method slightly. It now accepts a callback that is used to update the progress state. The implementation below utilizes the integrated functionality of axios:\n\n```ts\nexport const getUsers = (\n onDownloadProgress?: (progressEvent: {\n loaded: number;\n total: number;\n }) => void\n) =>\n client\n .get(\"/api/users\", {\n onDownloadProgress,\n })\n .then((res) => (res as AxiosResponse).data);\n```\n\nIf you just want to display a loading bar that goes backwards and forwards, you do not need to pass the `onDownloadProgress` event. All you need to do is use a timer to generate random values while the data is being loaded:\n\n```tsx\nfunction App() {\n let timer: number; // highlight-line\n const [progress, setProgress] = useState(0);\n const { data, isLoading } = useQuery(\"users\", () => getUsers(), {\n onSuccess: () => clearInterval(timer), // highlight-line\n });\n\n // highlight-start\n useEffect(() => {\n timer = setInterval(() => {\n setProgress((prev) => {\n if (prev === 100) {\n return 0;\n }\n return Math.min((prev + Math.random() * 20) % 100, 100);\n });\n }, 500);\n\n return () => {\n clearInterval(timer);\n };\n }, []);\n // highlight-end\n\n return (\n
\n {isLoading && }\n {isLoading && }\n {data && (\n \n \n \n \n \n \n \n \n \n {data.map((user) => (\n \n \n \n \n \n ))}\n \n
IDNameEmail
{user.id}{user.name}{user.email}
\n )}\n
\n );\n}\n\nconst TopbarLoading = styled(Linear)<{ value?: number }>`\n #progress rect {\n transition: width 0.5s;\n width: ${(props) => (props.value && `${props.value}px`) || \"unset\"};\n }\n`;\n\nexport default App;\n```","filePath":"src/content/blog/en/2021-09-01-showing-topbar-progress-indicator-in-react.md","digest":"d9c7223f622e9e3f","rendered":{"html":"

I use circular loading indicators in my React applications before data is returned from the server:

\n \"circular_loading\"\n

Which is a simple SVG file loaded as a React component:

\n
// other imports\nimport { ReactComponent as Circular } from \"./assets/CircularLoading.svg\";// highlight-line\n\nfunction App() {\n  const { data, isLoading } = useQuery<User[]>(\"users\", () => getUsers(), {})\n  return (\n    <div>\n      {isLoading && <Circular className=\"circular\" /> // highlight-line}\n      {data && (\n        <table>\n          <thead>\n            <tr>\n              <td>ID</td>\n              <td>Name</td>\n              <td>Email</td>\n            </tr>\n          </thead>\n          <tbody>\n            {data.map(user => (\n              <tr key={user.id}>\n                <td>{user.name}</td>\n                <td>{user.email}</td>\n              </tr>\n            ))}\n          </tbody>\n        </table>\n      )}\n    </div>\n  )\n}\n\nexport default App
\n

In one of our projects I was asked to add a topbar loading indicator:

\n \"linear_loading\"\n

Since it’s an SVG file, it’s pretty easy to do. However, it should be based on the elapsed time. As opposed to the first one, which spins as long as isLoading is set to true, for this one we will have to calculate the actual elapsed time and convert it to percentage, then use it as width for the loading indicator.

\n
function App() {\n  const [progress, setProgress] = useState(0) // highlight-line\n  const { data, isLoading } = useQuery<User[]>(\n    \"users\",\n    () =>\n      // highlight-start\n      getUsers(progressEvent => {\n        let percentCompleted = Math.floor(\n          (progressEvent.loaded / progressEvent.total) * 100\n        )\n        setProgress(percentCompleted)\n      }),\n    // highlight-end\n    {}\n  )\n  return (\n    <div>\n      {isLoading && <TopbarLoading value={progress} /> // highlight-line}\n      {isLoading && <Circular className=\"circular\" />}\n      {data && (\n        <table>\n          <thead>\n            <tr>\n              <td>ID</td>\n              <td>Name</td>\n              <td>Email</td>\n            </tr>\n          </thead>\n          <tbody>\n            {data.map(user => (\n              <tr key={user.id}>\n                <td>{user.id}</td>\n                <td>{user.name}</td>\n                <td>{user.email}</td>\n              </tr>\n            ))}\n          </tbody>\n        </table>\n      )}\n    </div>\n  )\n}\n\n// highlight-start\nconst TopbarLoading = styled(Linear)<{ value?: number }>`\n  #progress rect {\n    transition: width 0.5s;\n    width: ${props => (props.value && `${props.value}px`) || \"unset\"};\n  }\n`\n// highlight-end\n\nexport default App
\n

You can see from the code above that we changed the service method slightly. It now accepts a callback that is used to update the progress state. The implementation below utilizes the integrated functionality of axios:

\n
export const getUsers = (\n  onDownloadProgress?: (progressEvent: {\n    loaded: number;\n    total: number;\n  }) => void\n) =>\n  client\n    .get(\"/api/users\", {\n      onDownloadProgress,\n    })\n    .then((res) => (res as AxiosResponse).data);
\n

If you just want to display a loading bar that goes backwards and forwards, you do not need to pass the onDownloadProgress event. All you need to do is use a timer to generate random values while the data is being loaded:

\n
function App() {\n  let timer: number; // highlight-line\n  const [progress, setProgress] = useState(0);\n  const { data, isLoading } = useQuery<User[]>(\"users\", () => getUsers(), {\n    onSuccess: () => clearInterval(timer), // highlight-line\n  });\n\n  // highlight-start\n  useEffect(() => {\n    timer = setInterval(() => {\n      setProgress((prev) => {\n        if (prev === 100) {\n          return 0;\n        }\n        return Math.min((prev + Math.random() * 20) % 100, 100);\n      });\n    }, 500);\n\n    return () => {\n      clearInterval(timer);\n    };\n  }, []);\n  // highlight-end\n\n  return (\n    <div>\n      {isLoading && <TopbarLoading value={progress} />}\n      {isLoading && <Circular className=\"circular\" />}\n      {data && (\n        <table>\n          <thead>\n            <tr>\n              <td>ID</td>\n              <td>Name</td>\n              <td>Email</td>\n            </tr>\n          </thead>\n          <tbody>\n            {data.map((user) => (\n              <tr key={user.id}>\n                <td>{user.id}</td>\n                <td>{user.name}</td>\n                <td>{user.email}</td>\n              </tr>\n            ))}\n          </tbody>\n        </table>\n      )}\n    </div>\n  );\n}\n\nconst TopbarLoading = styled(Linear)<{ value?: number }>`\n  #progress rect {\n    transition: width 0.5s;\n    width: ${(props) => (props.value && `${props.value}px`) || \"unset\"};\n  }\n`;\n\nexport default App;
","metadata":{"headings":[],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"Showing Topbar Progress Indicator in React","date":"2021-09-01T23:46:37.121Z","template":"post","draft":false,"slug":"showing-topbar-progress-indicator-in-react","tags":["React","React Query","Axios","Vite"],"category":"Programming","description":"I use circular loading indicators in my React applications before data is returned from the server...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"showing-topbar-progress-indicator-in-react"},{"id":"en/2021-06-10-no-nested-ternary.md","data":{"title":"disallow nested ternary expressions (no-nested-ternary)","date":"2021-06-10T23:46:37.121Z","description":"We usually use ternary operator as a shortcut for `if` statement, For instance, in React applications we can use them to conditionally rendering elements inline...","template":"post","draft":false,"tags":["JS","TypeScript","Clean Code","Ternary Operator"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"We usually use ternary operator as a shortcut for `if` statement, For instance, in React applications we can use them to conditionally rendering elements inline:\n\n```tsx\n
{isLoggedIn ? : }
\n```\n\nIt's great until it's not. Let me give you an example, I had written the following piece of code in one of our projects:\n\n```ts\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...(recipeElement.Repeat\n ? {\n hour: `${fromTime[0]}-${toTime[0]}`,\n minutes: `*/${frequency[1]}`,\n }\n : {\n hour: fromTime[0],\n minutes: fromTime[1],\n }),\n },\n ],\n};\n```\n\nI was asked to change the code a little bit and add something on top of it:\n\n```ts\nconst hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...(recipeElement.Repeat\n ? frequency[0] === \"00\"\n ? {\n hour: timeSegements,\n minutes: `*/${frequency[1]}`,\n }\n : {\n hour: timeSegements,\n }\n : {\n hour: fromTime[0],\n minutes: fromTime[1],\n }),\n },\n ],\n};\n```\n\nAs you can see the nested ternary operator is not readable (I know it's called chained ternaries I just don't like them). Of course the code worked as expected but I didn't like it so I tried to change it to something like this:\n\n```ts\nconst hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...(recipeElement.Repeat\n ? {\n hour: timeSegements,\n ...(frequency[0] === \"00\" ? { minutes: `*/${frequency[1]}` } : {}),\n }\n : {\n hour: fromTime[0],\n minutes: fromTime[1],\n }),\n },\n ],\n};\n```\n\nA bit better, right? but it's still nested. Let's try something else:\n\n```ts\nconst hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...(() => {\n // You can also use switch/case if you want to\n\n if (!recipeElement.Repeat) {\n return {\n hour: fromTime[0],\n minutes: fromTime[1],\n };\n }\n\n if (frequency[0] === \"00\") {\n return {\n hour: timeSegements,\n minutes: `*/${frequency[1]}`,\n };\n }\n\n return {\n hour: timeSegements,\n };\n })(),\n },\n ],\n};\n```\n\nAs you can see I completely got rid of the ternary operators and replaced it with an IIFE. It's a bit long-winded but much better in terms of code readability. I know I could have moved it to a new function I didn't want to, for two main reason:\n\n- I am a lazy developer 😁\n- That's the only place where I use that logic (in terms of code reusability)\n\n### Let's do another small improvement, Shall we?\n\nI'm not saying I'm against using ternary operators, My point being is that using chained ternaries makes our code difficult to read, So I merged the last two return statments:\n\n```ts\nconst hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...(() => {\n // You can also use switch/case if you want to\n\n if (!recipeElement.Repeat) {\n return {\n hour: fromTime[0],\n minutes: fromTime[1],\n };\n }\n\n return {\n hour: timeSegements,\n ...(frequency[0] === \"00\" ? { minutes: `*/${frequency[1]}` } : {}),\n };\n })(),\n },\n ],\n};\n```\n\nYou might say, well, we don't need that long-winded IIFE we can just merge them all together:\n\n```ts\nconst hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n schedule: [\n {\n // lots of other props\n ...{\n hour: recipeElement.Repeat ? timeSegements : { hour: fromTime[0] },\n ...(frequency[0] === \"00\"\n ? { minutes: `*/${frequency[1]}` }\n : { minutes: fromTime[1] }),\n },\n },\n ],\n};\n```\n\nBut again it's not readable.","filePath":"src/content/blog/en/2021-06-10-no-nested-ternary.md","assetImports":["./covers/cover.png"],"digest":"f8b250a9ca15f579","rendered":{"html":"

We usually use ternary operator as a shortcut for if statement, For instance, in React applications we can use them to conditionally rendering elements inline:

\n
<div>{isLoggedIn ? <MainLayout /> : <LandingPage />}</div>
\n

It’s great until it’s not. Let me give you an example, I had written the following piece of code in one of our projects:

\n
const jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...(recipeElement.Repeat\n        ? {\n            hour: `${fromTime[0]}-${toTime[0]}`,\n            minutes: `*/${frequency[1]}`,\n          }\n        : {\n            hour: fromTime[0],\n            minutes: fromTime[1],\n          }),\n    },\n  ],\n};
\n

I was asked to change the code a little bit and add something on top of it:

\n
const hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...(recipeElement.Repeat\n        ? frequency[0] === \"00\"\n          ? {\n              hour: timeSegements,\n              minutes: `*/${frequency[1]}`,\n            }\n          : {\n              hour: timeSegements,\n            }\n        : {\n            hour: fromTime[0],\n            minutes: fromTime[1],\n          }),\n    },\n  ],\n};
\n

As you can see the nested ternary operator is not readable (I know it’s called chained ternaries I just don’t like them). Of course the code worked as expected but I didn’t like it so I tried to change it to something like this:

\n
const hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...(recipeElement.Repeat\n        ? {\n            hour: timeSegements,\n            ...(frequency[0] === \"00\" ? { minutes: `*/${frequency[1]}` } : {}),\n          }\n        : {\n            hour: fromTime[0],\n            minutes: fromTime[1],\n          }),\n    },\n  ],\n};
\n

A bit better, right? but it’s still nested. Let’s try something else:

\n
const hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...(() => {\n        // You can also use switch/case if you want to\n\n        if (!recipeElement.Repeat) {\n          return {\n            hour: fromTime[0],\n            minutes: fromTime[1],\n          };\n        }\n\n        if (frequency[0] === \"00\") {\n          return {\n            hour: timeSegements,\n            minutes: `*/${frequency[1]}`,\n          };\n        }\n\n        return {\n          hour: timeSegements,\n        };\n      })(),\n    },\n  ],\n};
\n

As you can see I completely got rid of the ternary operators and replaced it with an IIFE. It’s a bit long-winded but much better in terms of code readability. I know I could have moved it to a new function I didn’t want to, for two main reason:

\n
    \n
  • I am a lazy developer 😁
  • \n
  • That’s the only place where I use that logic (in terms of code reusability)
  • \n
\n

Let’s do another small improvement, Shall we?

\n

I’m not saying I’m against using ternary operators, My point being is that using chained ternaries makes our code difficult to read, So I merged the last two return statments:

\n
const hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...(() => {\n        // You can also use switch/case if you want to\n\n        if (!recipeElement.Repeat) {\n          return {\n            hour: fromTime[0],\n            minutes: fromTime[1],\n          };\n        }\n\n        return {\n          hour: timeSegements,\n          ...(frequency[0] === \"00\" ? { minutes: `*/${frequency[1]}` } : {}),\n        };\n      })(),\n    },\n  ],\n};
\n

You might say, well, we don’t need that long-winded IIFE we can just merge them all together:

\n
const hourRangeSegements = `${fromTime[0]}-${endTime[0]}`;\nconst jsonResult = {\n  schedule: [\n    {\n      // lots of other props\n      ...{\n        hour: recipeElement.Repeat ? timeSegements : { hour: fromTime[0] },\n        ...(frequency[0] === \"00\"\n          ? { minutes: `*/${frequency[1]}` }\n          : { minutes: fromTime[1] }),\n      },\n    },\n  ],\n};
\n

But again it’s not readable.

","metadata":{"headings":[{"depth":3,"slug":"lets-do-another-small-improvement-shall-we","text":"Let’s do another small improvement, Shall we?"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"disallow nested ternary expressions (no-nested-ternary)","date":"2021-06-10T23:46:37.121Z","template":"post","draft":false,"slug":"no-nested-ternary","tags":["JS","TypeScript","Clean Code","Ternary Operator"],"category":"Programming","description":"We usually use ternary operator as a shortcut for `if` statement, For instance, in React applications we can use them to conditionally rendering elements inline...","lang":"en","cover":"./covers/cover.png"},"imagePaths":[]}},"collection":"blog","slug":"no-nested-ternary"},{"id":"en/2023-04-03-stolen-iphone.md","data":{"title":"iPhone","date":"2023-04-03T23:46:37.121Z","description":"On April 30, 2023, I was out with my friend, and we were traveling back home from London Waterloo to Guildford. We had to wait a couple of hours for the train to Guildford, so we decided to pass the time by traveling back and forth from Waterloo to the Northern line. While on the tube, both of us fell asleep, and my phone was on my lap...","template":"post","draft":false,"tags":["iPhone","London"],"category":"","lang":"en"},"body":"On April 30, 2023, I was out with my friend, and we were traveling back home from London Waterloo to Guildford. We had to wait a couple of hours for the train to Guildford, so we decided to pass the time by traveling back and forth from Waterloo to the Northern line. While on the tube, both of us fell asleep, and my phone was on my lap.\n\nAs soon as we woke up on the tube, we noticed that my phone was missing. We promptly headed to the help point and contacted a member of staff. The staff member recorded the incident and advised us to report it to the police, which we did upon arrival in Guildford.\n\n
\n \"help_point_station\"\n
\n Stations have 24/7 Help Points for service information and emergencies, connecting you to a team member or the British Transport Police.\n
\n
\n\nI used my Apple Watch to set my iPhone to Lost Mode via the Find My app. When I arrived home, I took immediate action to protect my personal information. I terminated active sessions for the apps and used the Find My app to erase the phone data. However, the process of erasing the phone data takes time, so I'm uncertain if it was successful or not. According to the map on the Find My app, the thief was moving around in London. However, the problem was that I had already suspended my SIM card, which meant that I lost the location of the phone.\n\n\"sirwan_find_my_iphone\"\n\nMy friend called the police, but they said they needed access to my Apple account, which I was hesitant to provide. I then called the police myself and explained the situation. I suggested providing the live location of the phone, but the police reiterated that they could not just randomly follow people on the street. They advised me to try and find a fixed location where the phone might be, such as a building or public space. I tried to find a fixed location, but the thief was moving around, and I could not find a fixed location.\n\n### Lessons learned for me:\n\n- Always keep your phone in your pocket 😃\n- Enable Find My on your iPhone.\n- Backup your data regularly.\n\nPS: I lost all the shortcuts I had created on my iPhone as they were not backed up, and had to recreated them again. These shortcuts were used in automating the update process of my daily step count and latest blog posts on my GitHub profile. (https://github.com/SirwanAfifi)","filePath":"src/content/blog/en/2023-04-03-stolen-iphone.md","digest":"cbbb99bac2cceeb4","rendered":{"html":"

On April 30, 2023, I was out with my friend, and we were traveling back home from London Waterloo to Guildford. We had to wait a couple of hours for the train to Guildford, so we decided to pass the time by traveling back and forth from Waterloo to the Northern line. While on the tube, both of us fell asleep, and my phone was on my lap.

\n

As soon as we woke up on the tube, we noticed that my phone was missing. We promptly headed to the help point and contacted a member of staff. The staff member recorded the incident and advised us to report it to the police, which we did upon arrival in Guildford.

\n
\n \"help_point_station\"\n
\n Stations have 24/7 Help Points for service information and emergencies, connecting you to a team member or the British Transport Police.\n
\n
\n

I used my Apple Watch to set my iPhone to Lost Mode via the Find My app. When I arrived home, I took immediate action to protect my personal information. I terminated active sessions for the apps and used the Find My app to erase the phone data. However, the process of erasing the phone data takes time, so I’m uncertain if it was successful or not. According to the map on the Find My app, the thief was moving around in London. However, the problem was that I had already suspended my SIM card, which meant that I lost the location of the phone.

\n\"sirwan_find_my_iphone\"\n

My friend called the police, but they said they needed access to my Apple account, which I was hesitant to provide. I then called the police myself and explained the situation. I suggested providing the live location of the phone, but the police reiterated that they could not just randomly follow people on the street. They advised me to try and find a fixed location where the phone might be, such as a building or public space. I tried to find a fixed location, but the thief was moving around, and I could not find a fixed location.

\n

Lessons learned for me:

\n
    \n
  • Always keep your phone in your pocket 😃
  • \n
  • Enable Find My on your iPhone.
  • \n
  • Backup your data regularly.
  • \n
\n

PS: I lost all the shortcuts I had created on my iPhone as they were not backed up, and had to recreated them again. These shortcuts were used in automating the update process of my daily step count and latest blog posts on my GitHub profile. (https://github.com/SirwanAfifi)

","metadata":{"headings":[{"depth":3,"slug":"lessons-learned-for-me","text":"Lessons learned for me:"}],"localImagePaths":[],"remoteImagePaths":[],"frontmatter":{"title":"iPhone","date":"2023-04-03T23:46:37.121Z","template":"post","draft":false,"slug":"iphone-theft","tags":["iPhone","London"],"category":"","description":"On April 30, 2023, I was out with my friend, and we were traveling back home from London Waterloo to Guildford. We had to wait a couple of hours for the train to Guildford, so we decided to pass the time by traveling back and forth from Waterloo to the Northern line. While on the tube, both of us fell asleep, and my phone was on my lap...","lang":"en"},"imagePaths":[]}},"collection":"blog","slug":"iphone-theft"},{"id":"en/2021-05-19-OS-Notification.md","data":{"title":"OS Notification","date":"2021-05-19T23:46:37.121Z","description":"I recently tweeted something about a little script I had put together to automate one of the tasks I had always struggle with. I thought it would be a good idea to share the process in a little bit more detail:","template":"post","draft":false,"tags":["macOS","Windows","AppleScript","Powershell"],"category":"Programming","lang":"en","cover":{"src":"/assets/cover.HhrAMmzi.png","width":1080,"height":596,"format":"png"}},"body":"I recently tweeted something about a little script I had put together to automate one of the tasks I had always struggle with. I thought it would be a good idea to share the process in a little bit more detail:\n\n

کلاً خیلی علاقه دارم کارهای روتین‌ رو اتوماتیک کنم، یه مدته یه schedule task نوشتم که هر نیم ساعت یکبار بهم هشدار میده که زیاد پشت کامپیوتر نباشم و کمی قدم بزنم؛ الان هم نوتیفیکشن میده هم یه خانم با لهجه‌ی بریتیش و صدای زیباش بهم یادآوری میکنه 😀 pic.twitter.com/E7RneW9W28

— Sirwan Afifi (@SirwanAfifi) May 15, 2021