2021-09-30

React Custom hook - useQueryString

Custom hook for simple get and set QueryString

demo

install package react-router-dom

// src/index.js
  import { StrictMode } from "react";
  import ReactDOM from "react-dom";
+ import { BrowserRouter as Router } from "react-router-dom";

  import App from "./App";

  const rootElement = document.getElementById("root");
  ReactDOM.render(
    <strictmode>
+      <router>
        <app>
+      </app></router>
    </strictmode>,
    rootElement
  );

Add useQueryString.js

// src/hooks/useQueryString.js
import React from "react";
import { useLocation, useHistory } from "react-router-dom";
import { shallowEqual } from "react-redux";

const useQueryString = () =&gt; {
  const location = useLocation();
  const history = useHistory();
  const { search } = location;
  const [value, setValue] = React.useState({});

  React.useEffect(() =&gt; {
    let qs = Object.fromEntries(new URLSearchParams(search));
    if (!shallowEqual(qs, value)) {
      setValue(qs);
    }
  }, [search]); // eslint-disable-line react-hooks/exhaustive-deps

  return {
    value,
    set: (params) =&gt;
      history.push({
        pathname: location.pathname,
        search: new URLSearchParams({ ...value, ...params }).toString()
      })
  };
};

export default useQueryString;

I use shallowEqual function check queryString is changed.

// shallowEqual.js in react-redux
function is(x, y) {
  if (x === y) {
    return x !== 0 || y !== 0 || 1 / x === 1 / y;
  } else {
    return x !== x &amp;&amp; y !== y;
  }
}

export default function shallowEqual(objA, objB) {
  if (is(objA, objB)) return true;

  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
    return false;
  }

  var keysA = Object.keys(objA);
  var keysB = Object.keys(objB);
  if (keysA.length !== keysB.length) return false;

  for (var i = 0; i &lt; keysA.length; i++) {
    if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }

  return true;
}

How to use useQueryString()

const qs = useQueryString();

set value to url

qs.set({"name": "value"});
qs.set({"age": "19"});

get value

console.log(qs.value.name);
console.log(qs.value.age);

References

2021-04-07

ValueObject as Entity ID, EntityTypeConfiguration Sample

問題:https://stackoverflow.com/questions/53328201/ef-core-non-primitive-type-value-object-as-primary-key 參考來源:https://github.com/dotnet/efcore/issues/13669

public class User
    {
        public UserId Id { get; set; }
        public Credentials Credentials { get; set; }
    }

    public class UserId
    {
        private UserId()
        {

        }

        private UserId(long id)
        {
            Id = id;
        }

        public long Id { get; private set; }

        public static implicit operator long(UserId beaconId)
        {
            return beaconId.Id;
        }

        public static implicit operator UserId(long id)
        {
            return new UserId(id);
        }
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            var userId = (UserId) obj;
            return this.Id == userId.Id;
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }

public class TestDbContext: DbContext
    {
        public TestDbContext(DbContextOptions options): base(options)
        {

        }

        public DbSet<user> Users { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

           var userModelBuilder = modelBuilder.Entity<user>();

            userModelBuilder.Property(x =&gt; x.Id).HasConversion(x =&gt; x.Id, value =&gt; new UserId(value)).HasColumnName("Id").IsRequired();

            userModelBuilder.OwnsOne(x =&gt; x.Credentials, c =&gt;
            {
                c.Property(x =&gt; x.Email);
                c.Property(x =&gt; x.Password);
            });
        }
    }

2021-03-31

dotnet core get k8s self POD name

k8s 中的 dotnet core 應用取得 POD name

三種方式取得的結果相同

class Program
{
  static async Task Main(string[] args)
  {
   Console.WriteLine("MachineName:"+Environment.MachineName);
   Console.WriteLine("HostName:"+ System.Net.Dns.GetHostName());
   Console.WriteLine("ENV K8S_POD_NAME:"+Environment.GetEnvironmentVariable("K8S_POD_NAME"));

   await Task.Run(() =〉 Thread.Sleep(Timeout.Infinite));
  }
}

result on dotnet 3.1.11-alpine3.12

MachineName:mqsend-7d9579cc47-kld6v
HostName:mqsend-7d9579cc47-kld6v
ENV K8S_POD_NAME:mqsend-7d9579cc47-kld6v

ENV需要在deployment時額外加入參考

    spec:
      containers:
      - env:
        - name: K8S_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

ref

  • https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#use-container-fields-as-values-for-environment-variablesƒ

2021-01-29

Adding Git-Bash to the new Windows Terminal

在 Terminal 按下 ctrl + ,,會開啟 settings.json

{
    "$schema": "https://aka.ms/terminal-profiles-schema",

    "defaultProfile": "{00000000-0000-0000-ba54-000000000001}",

    "profiles":
    {
        "defaults":
        {
            // Put settings here that you want to apply to all profiles
        },
        "list":
        [
            // put one of the configuration below right here
        ]
    }
}

在 list 的區段中加入,依據正確git安裝路徑取消commandlineicon的註解

{
  "guid": "{00000000-0000-0000-ba54-000000000002}",
  //"commandline": "%PROGRAMFILES%/git/usr/bin/bash.exe -i -l",
  //"commandline": "%USERPROFILE%/AppData/Local/Programs/Git/git-bash.exe -l -i",
  "commandline": "%USERPROFILE%/AppData/Local/Programs/Git/bin/sh.exe --login",
  //"commandline": "%USERPROFILE%/AppData/Local/Programs/Git/bin/bash.exe -l -i",
  //"commandline": "%USERPROFILE%/scoop/apps/git/current/usr/bin/bash.exe -l -i",
  //"icon": "%PROGRAMFILES%/Git/mingw64/share/git/git-for-windows.ico",
  "icon": "%USERPROFILE%/AppData/Local/Programs/Git/mingw64/share/git/git-for-windows.ico",
  // "icon": "%USERPROFILE%/apps/git/current/usr/share/git/git-for-windows.ico",
  "name": "Bash",
  "startingDirectory": "%USERPROFILE%"
}

Reference

Adding Git-Bash to the new Windows Terminal

adsense