Skip to content

Instantly share code, notes, and snippets.

@grbull
grbull / useInterval.ts
Created July 15, 2025 16:25
useInterval.ts
import { useEffect, useRef } from 'react';
// Source: https://overreacted.io/making-setinterval-declarative-with-react-hooks/
export function useInterval(callback: () => void, delay: number | null): void {
const savedCallback = useRef<() => void>();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
@grbull
grbull / docker-compose.yml
Created March 26, 2025 22:42
hapi fhir sql server
services:
hapi-fhir:
image: 'hapiproject/hapi:latest'
ports:
- 8080:8080
environment:
SPRING_DATASOURCE_URL: jdbc:sqlserver://sql-server:1433;databaseName=hapi;trustServerCertificate=true
SPRING_DATASOURCE_USERNAME: sa
SPRING_DATASOURCE_PASSWORD: YourStrong@Passw0rd
SPRING_DATASOURCE_DRIVERCLASSNAME: com.microsoft.sqlserver.jdbc.SQLServerDriver
@grbull
grbull / partialBy.ts
Created May 11, 2024 13:08
PartialBy
// Source: https://stackoverflow.com/a/54178819
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
@grbull
grbull / FakeUserManager.cs
Created March 27, 2023 20:33
FakeUserManager
public class FakeUserManager : UserManager<ApplicationUser>
{
public FakeUserManager()
: base(new Mock<IUserRoleStore<ApplicationUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<ApplicationUser>>().Object,
new IUserValidator<ApplicationUser>[0],
new IPasswordValidator<ApplicationUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
@grbull
grbull / resolveSynchronously.js
Last active September 25, 2022 00:33
resolveSynchronously
const resolveSynchronously = async (promises) => {
return promises.reduce(async (prevPromise, nextPromise) => {
await prevPromise;
return nextPromise();
}, Promise.resolve());
};
const promise = () =>
new Promise((resolve) => {
setTimeout(() => {
@grbull
grbull / Anything.ts
Created February 23, 2022 20:14
useQuery
const order = useQuery(['order']); // Use this in OrderPanel
const getOrder = useQuery(['order'], () => fetchOrderById(todoId)); // Use this in OrderGetForm
const createOrder = useMutation((orderCreateDto) => createOrder(orderCreateDto), {
onSuccess: (orderDto) => {
queryClient.setQueryData(['order], orderDto);
}
});
// Etc
@grbull
grbull / ContextSetState.ts
Created February 19, 2022 11:34
Context with SetState
import { createContext, Dispatch, SetStateAction } from 'react';
export interface CatFact {
fact: string;
length: number;
}
export const CatFactContext = createContext<[CatFact | undefined, Dispatch<SetStateAction<CatFact | undefined>>]>([
undefined,
(): void => undefined,
@grbull
grbull / SearchDuck.ts
Created February 17, 2022 10:53
SearchDuck
import { ActionsObservable, ofType } from 'redux-observable';
import { Observable, of } from 'rxjs';
import { AjaxError } from 'rxjs/ajax';
import { catchError, map, switchMap } from 'rxjs/operators';
import { searchSeries } from '../../utils/api/tvmaze';
import { SeriesSearch } from '../../utils/api/tvmaze.types';
import { GlobalState } from './index';
// Actions
@grbull
grbull / SeriesDuck.ts
Created February 17, 2022 10:52
SeriesDuck
import {
ActionsObservable,
combineEpics,
Epic,
ofType,
StateObservable,
} from 'redux-observable';
import { from, iif, Observable, of, zip } from 'rxjs';
import { AjaxError } from 'rxjs/ajax';
import {
@grbull
grbull / UserDuck.ts
Created February 17, 2022 10:39
UserDuck.ts
import {
ActionsObservable,
combineEpics,
Epic,
ofType,
} from 'redux-observable';
import { Observable, of } from 'rxjs';
import { AjaxError } from 'rxjs/ajax';
import { catchError, map, mergeMap, switchMap } from 'rxjs/operators';