�������� Full Stack Snippets.
A variety of code snippets, from backend to frontend, written in a clean-as-I-can-make-it style, ready for you to copy and paste wherever you may need them.
Check out the Full Stack Goodies page for a full PDF of these snippets, organized by language and level of the stack you would use them.
For TypeScript snippets, be sure to check out the magical JavaScript switch if you would like the snippet in vanilla JavaScript.
Client
mergeArrays
Merges all properties of all objects from a less complex object array to the more complex object array. The more complex object type must extend the less complex type.
From post: Advanced TypeScript: A Generic Function to Merge Object Arrays
mergeArrays.ts
export const mergeArrays = <T, U extends T>(params: {mergeArray: Array<T>existingArray: Array<U>matchKey: keyof T}): Array<U> => {const { mergeArray, existingArray, matchKey } = paramsreturn existingArray.map((existingItem) => {const match = mergeArray.find((mergeItem) => mergeItem[matchKey] === existingItem[matchKey])if (match) {return Object.assign(existingItem, match)}return existingItem})}
Usage
// Given interface IFile:export interface IFile {fileLabel: stringcode: string}// and interface IEditorSetting:export interface IEditorSetting extends IFile {isActive: boolean}// and array editorSettingsState, which is of type Array<IEditorSetting>:const editorSettingsState: Array<IEditorSetting> = [{fileLabel: 'myJSFile.js',code: '// some JS comment',isActive: false},{fileLabel: 'myHTMLFile.html',code: '<h1>hello world</h1>',isActive: true},{fileLabel: 'myCSSFile.css',code: 'h1 { color: red; }',isActive: false}]// and some incoming files from an API or similar:const files: Array<IFile> = [{fileLabel: 'myJSFile.js',code: '// awesome server generated code'},{fileLabel: 'myHTMLFile.js',code: '<h1>awesome generated code</h1>'},{fileLabel: 'myCSSFile.css',code: 'h1 { color: blue; font-weight: bold; }'},]// This will return a new array of type Array<IEditorSetting>,// with the code updated the code for all files WITHOUT changing the isActive property (since isActive is not in IFile)const mergedArray = mergeArrays({mergeArray: files,existingArray: editorSettingsState,matchKey: "fileLabel"})
updateArray
Updates an object array at the specified update key with the update value, if the specified test key matches the test value. Optionally pass 'testFailValue' to set a default value if the test fails.
From post: Advanced TypeScript: A Generic Function to Update and Manipulate Object Arrays
updateArray.ts
export const updateArray = <T, U extends keyof T, V extends keyof T>(params: {array: Array<T>testKey: keyof TtestValue: T[U]updateKey: keyof TupdateValue: T[V]testFailValue?: T[V]}): Array<T> => {const {array,testKey,testValue,updateKey,updateValue,testFailValue,} = optionsreturn array.map((item) => {if (item[testKey] === testValue) {item[updateKey] = updateValue} else if (testFailValue !== undefined) {item[updateKey] = testFailValue}return item})}
Usage
import { updateArray } from "../../../../frontend/typescript/utils/updateArray"// Given interface IEditorSetting:export default interface IEditorSetting {fileLabel: stringcode: stringisActive: boolean}// and array editorSettingsState, which is of type Array<IEditorSetting>:const editorSettingsState: Array<IEditorSetting> = [{fileLabel: 'myJSFile.js',code: '// some JS comment',isActive: false},{fileLabel: 'myHTMLFile.html',code: '<h1>hello world</h1>',isActive: true},{fileLabel: 'myCSSFile.css',code: 'h1 { color: red; }',isActive: false}]const code = "<p>some new HTML code for the html editor</p>"// This will return a new array of type Array<IEditorSetting>,// with the code updated the code ONLY for the editor(s) which isActive = trueconst updatedArray = updateArray({array: editorSettingsState,testKey: "isActive",testValue: true,updateKey: "code",updateValue: code,})
useDidMount
Tiny hook to know when a React component has mounted.
From post: Let's Build a Snazzy Animated Sticky Footer For GDPR Compliance!
useDidMount.ts
import { useState, useEffect } from 'react'export const useDidMount = (): boolean => {const [didMount, setDidMount] = useState<boolean>(false)useEffect(() => {setDidMount(true)}, [])return didMount}
Usage
import * as React from "react"import { useDidMount } from "./hooks/useDidMount"export function ExampleComponent() {const didMount = useDidMount()if (didMount) {console.log("I am mounted! Things like the DOM and window are available! Or, you could run some animation you were waiting to run!")}return <></>}
useAppSelector
Officially recommended hook to get a typed selector when using Redux with TypeScript.
From post: TypeScript, Redux Toolkit, React Hooks, and Gatsby
useAppSelector.ts
import { TypedUseSelectorHook, useSelector } from "react-redux";import { RootState } from "../store";export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
Usage
import * as React from "react"import { useAppSelector } from "./hooks/useAppSelector"export function ExampleComponent() {// complexTypedPartOfSlice here will be typed just as defined in the slice.// TypeScript also won't complain about state missing a typing,// since it's been typed in the definition for useAppSelector!const { complexTypedPartOfSlice } = useAppSelector((state) => state.someSliceOfState)return <>Hello world!</>}
useAppDispatch
Officially recommended hook to get a typed dispatch when using Redux with TypeScript.
From post: TypeScript, Redux Toolkit, React Hooks, and Gatsby
useAppDispatch.ts
import { useDispatch } from "react-redux";import { AppDispatch } from "../store";export const useAppDispatch = () => useDispatch<AppDispatch>()
Usage
import * as React from "react"import { useAppDispatch } from "./hooks/useAppDispatch"export function ExampleComponent() {// here 'dispatch' will have the correct typing depending on// which middleware(s) you are using!const dispatch = useAppDispatch()const handleButtonClick = () => {dispatch(someReduxAction())}return <button onClick={handleButtonClick}>Click me!</button>}
sendSlackMessage
Leverages the fetch API to post a slack message to your Slack webhook with a one-liner.
From post: Fully Automating Chrisfrew.in Productions - Part 4 of ??? - Building a Slack Bot
sendSlackMessage.ts
export const sendSlackMessage = (message: string): void => {process.env.SLACK_WEBHOOK_URL &&fetch(process.env.SLACK_WEBHOOK_URL, {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({text: message,}),})}
Usage
import { sendSlackMessage } from "./sendSlackMessage";// Send the message!sendSlackMessage("Hello world!")
Backend
JavaScript (Node.js)
sendSlackMessage
A Node.js compatible (using node-fetch) function that lets you send a Slack message with a one-liner.
From post: Fully Automating Chrisfrew.in Productions - Part 4 of ??? - Building a Slack Bot
sendSlackMessage.ts
import fetch from "node-fetch";export const sendSlackMessage = (message: string): void => {process.env.SLACK_WEBHOOK_URL &&fetch(process.env.SLACK_WEBHOOK_URL, {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({text: message,}),})}
Usage
import { sendSlackMessage } from "./sendSlackMessage";// Send the message!sendSlackMessage("Hello world!")
C#
PatchFiltererService
Filter out unwanted properties from your models on the server side in .NET.
PatchFiltererService.cs
using System;using System.Linq;using Microsoft.AspNetCore.JsonPatch;namespace JsonPatchFilterExample.Services{// a security filter for JSON patch filter operations// see the full blog post at https://chrisfrew.in/blog/filtering-json-patch-in-c-sharp/public static class PatchFiltererService{public static JsonPatchDocument<T> ApplyAttributeFilterToPatch<T, TU>(JsonPatchDocument<T> patch)where T : classwhere TU : Attribute{// Get path for all attributes of type TU that are in type Tvar allowedPaths = typeof(T).GetProperties().Where(x => x.GetCustomAttributes(false).OfType<TU>().Any()).Select(x => x.Name);// Now build a new JSONPatchDocument based on properties in T that were found abovevar filteredPatch = new JsonPatchDocument<T>();patch.Operations.ForEach(x =>{if (allowedPaths.Contains(x.path)){filteredPatch.Operations.Add(x);}});return filteredPatch;}}}
Usage
using System;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.JsonPatch;using JsonPatchFilterExample.Services;using JsonPatchFilterExample.Models;using System.ComponentModel.DataAnnotations;using Microsoft.Extensions.FileProviders;using System.IO;using Newtonsoft.Json;namespace JsonPatchFilterExample.Controllers{[Route("api/[controller]")][ApiController]public class WidgetController : ControllerBase{[HttpPatch("{id}")]public ActionResult Patch(Guid id, [FromBody] JsonPatchDocument<WidgetModel> patch){try{// For now, load the widget from the json file - ideally this would be retrieved via a repository from a databasevar physicalProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());var jsonFilePath = Path.Combine(physicalProvider.Root, "App_Data", "ExampleWidget.json");var item = new WidgetModel();using (var reader = new StreamReader(jsonFilePath)){var content = reader.ReadToEnd();item = JsonConvert.DeserializeObject<WidgetModel>(content);}if (item.Id != id || patch == null){return NotFound();}// Create a new patch to match only the type and attributes passedpatch = PatchFiltererService.ApplyAttributeFilterToPatch<WidgetModel, StringLengthAttribute>(patch);// Apply the patch!patch.ApplyTo(item);// Update updated time - normally would be handled in a repositoryitem.Updated = DateTime.Now;// Update the item - ideally this would also be done with a repository via an 'Update' method// write JSON directly to a filevar json = JsonConvert.SerializeObject(item);//write string to fileSystem.IO.File.WriteAllText(jsonFilePath, json);return Ok();}catch{return UnprocessableEntity();}}}}
AssertPropertiesAreNonNullService
Assert that all required, or simple all properties on your objects are not null.
From post: Recursively Assert All Properties Are Non-null Using Reflection
AssertPropertiesAreNonNullService.cs
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using Shouldly;namespace AssertPropertiesAreNonNullExample {public static class AssertPropertiesAreNonNullService{// Asserts that all required properties (via the 'Required' attribute) be non null// Optionally include all properties if desiredprivate static void AssertPropertiesAreNonNull<T>(T obj, bool onlyRequiredProperties = true){if (obj == null){return;}var objType = obj.GetType();// Get either all or only required propertiesvar properties = onlyRequiredProperties ? objType.GetProperties().Where(x => x.GetCustomAttributes(false).OfType<RequiredAttribute>().Any()) :objType.GetProperties();foreach (var property in properties){var propValue = property.GetValue(obj, null);var elems = propValue as IList<object>;// Another layerif (elems != null){foreach (var item in elems){AssertPropertiesAreNonNull(item, onlyRequiredProperties);}}else{if (property.PropertyType.Assembly == objType.Assembly){AssertPropertiesAreNonNull(propValue, onlyRequiredProperties);}// Reached the end of the treeelse{propValue.ShouldNotBeNull();}}}}}}
Usage
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using AssertPropertiesAreNonNullService;public class SomethingNested{[Required]public string SomeString { get; set; }[Required]public int SomeNumber { get; set; }public bool SomeBoolean { get; set; }public List<string> SomeStringList { get; set; }}public class MyWidget{[Required]public SomethingNested SomethingNested { get; set; }public string SomeString { get; set; }public int SomeNumber { get; set; }public bool SomeBoolean { get; set; }[Required]public List<string> SomeStringList { get; set; }}public class Program{public static void Main(){// Declare some object you want to check for null valuesvar myWidget = new MyWidget{SomethingNested = new SomethingNested{SomeString = null,SomeNumber = 123,SomeBoolean = true,SomeStringList = new List<string> { "a", "b", null }},SomeString = null,SomeNumber = 123,SomeBoolean = true,SomeStringList = null};// Only run for required properties of myWidgetAssertPropertiesAreNonNullService.AssertPropertiesAreNonNull(myWidget);// Run for ALL properties in myWidgetAssertPropertiesAreNonNullService.AssertPropertiesAreNonNull(myWidget, false);}}
Devops
Bash
buildColorPrompt
Letter-level color changes for your bash prompt!
From post: Awesome Colors for Shell Prompts!
buildColorPrompt.sh
function buildColorPrompt() {# I always like showing what directory I am in (special character "\w" in PS1) - store the equivalent in this 'directory' variabledirectory=$(pwd)# Modify these to whatever you'd like!PROMPT_TEXT="awesome-shell-prompt-colors@awesome-machine [$directory] "# Colors seperated by comma - acceptable values are:# black, white, red, green, yellow, blue, magenta, cyan, light gray, light red, light green, light yellow, light blue, light magenta, light cyanPROMPT_COLORS="red,white,blue"# Colors!BLACK="\e[30m"WHITE="\e[97m"RED="\e[31m"GREEN="\e[32m"YELLOW="\e[33m"BLUE="\e[34m"MAGENTA="\e[35m"CYAN="\e[36m"LIGHT_GRAY="\e[37m"DARK_GRAY="\e[90m"LIGHT_RED="\e[91m"LIGHT_GREEN="\e[92m"LIGHT_YELLOW="\e[93m"LIGHT_BLUE="\e[94m"LIGHT_MAGENTA="\e[95m"LIGHT_CYAN="\e[96m"# End formatting stringEND_FORMATTING="\[\e[0m\]"# split PROMPT_COLORS into arraycount=0IFS=','for x in $PROMPT_COLORSdocolors_array[$count]=$x((count=count+1))doneunset IFS# break PROMPT_TEXT into character arrayletters=()for (( i=0 ; i < ${#PROMPT_TEXT} ; i++ )) {letters[$i]=${PROMPT_TEXT:$i:1}}# build prompt with colorscolor_index=0ps1='\['for (( i=0 ; i < ${#letters[@]} ; i++ )) {# Determine color in this giant case statementcolor="${colors_array[color_index]}"case $color in"black")COLOR=$BLACK;;"red")COLOR=$RED;;"green")COLOR=$GREEN;;"yellow")COLOR=$YELLOW;;"blue")COLOR=$BLUE;;"magenta")COLOR=$MAGENTA;;"cyan")COLOR=$CYAN;;"light gray")COLOR=$LIGHT_GRAY;;"dark gray")COLOR=$DARK_GRAY;;"light red")COLOR=$LIGHT_RED;;"light green")COLOR=$LIGHT_GREEN;;"light yellow")COLOR=$LIGHT_YELLOW;;"light blue")COLOR=$LIGHT_BLUE;;"light magenta")COLOR=$LIGHT_MAGENTA;;"light cyan")COLOR=$LIGHT_CYAN;;"white")COLOR=$WHITE;;*)COLOR=$WHITE;;esac# add to ps1 var - color, then letter, then the end formatterps1+=$COLOR"${letters[$i]}"# reset color index if we are at the end of the color array, otherwise increment itif (( $color_index == ${#colors_array[@]} - 1 ))thencolor_index=0else((color_index=color_index+1))fi}ps1+="$END_FORMATTING\]"# Finally: set the PS1 variablePS1=$ps1}# Set the special bash variable PROMPT_COMMAND to our custom functionPROMPT_COMMAND=buildColorPrompt;
Usage
# Assuming the buildColorPrompt function is in your .bash_profile:# Set the special bash variable PROMPT_COMMAND to our custom functionPROMPT_COMMAND=buildColorPrompt;
sendSlackMessage
Util function to send a Slack message from bash.
From post: The Last Bitbucket Pipelines Tutorial You'll Ever Need: Mastering CI and CD
sendSlackMessage.sh
function sendSlackMessage {curl -X POST -H 'Content-type: application/json' --data '{"text":"$1"}' $2}
Usage
# the two parameters are 1. the message, and 2. the webhook urlsendSlackMessage "Hello World!" https://yourslackwebhookurl/secret/supersecret
supercurl
Get detailed network times for a website.
From post: Magento 2 IP Location Detection (GeoIP) and Store Context Control Using the ipstack API
supercurl.sh
function supercurl() {curl -s -w '\nLookup time:\t%{time_namelookup}\nConnect time:\t%{time_connect}\nAppCon time:\t%{time_appconnect}\nRedirect time:\t%{time_redirect}\nPreXfer time:\t%{time_pretransfer}\nStartXfer time:\t%{time_starttransfer}\n\nTotal time:\t%{time_total}\n' -o /dev/null $1}
Usage
# simply pass the website you want "super" curl as the first argument :)supercurl google.com# example output:# Lookup time: 0.061647# Connect time: 0.281195# AppCon time: 0.000000# Redirect time: 0.000000# PreXfer time: 0.281248# StartXfer time: 0.759128# Total time: 0.761387
zsh
buildColorPrompt
Letter-level color changes for your zsh prompt!
From post: Awesome Colors for Shell Prompts!
buildColorPrompt.sh
function buildColorPrompt() {# I always like showing what directory I am indirectory=$(pwd)# Modify these to whatever you'd like!PROMPT_TEXT="youruser@yourmachine [$directory]"# Comma seperated colors - as many or as few as you'd likePROMPT_COLORS="15"# This will be the color of everything in the input part of the prompt (here set to 15 = white)PROMPT_INPUT_COLOR="15"# split PROMPT_COLORS into arraycolors_array=("${(@s/,/)PROMPT_COLORS}") # @ modifier# break PROMPT_TEXT into character arrayletters=()for (( i=1 ; i < ${#PROMPT_TEXT}+1 ; i++ )) {letters[$i]=${PROMPT_TEXT:$i-1:1}}# build prompt with colorscolor_index=1ps1=""for (( i=1 ; i < ${#letters[@]}+1 ; i++ )) {# Determine color in this giant case statementcolor="${colors_array[color_index]}"# add to ps1 var - color, then letter, then the end formatterps1+="%F{$color}${letters[$i]}"# reset color index if we are at the end of the color array, otherwise increment itif (( $color_index == ${#colors_array[@]} ))thencolor_index=1else((color_index=color_index+1))fi}# end color formatingps1+="%F{$PROMPT_INPUT_COLOR} %# "# Finally: set the PROMPT variablePROMPT=$ps1}# set the precmd() hook to our custom functionprecmd() {buildColorPrompt;}
Usage
# Assuming the buildColorPrompt function is in your .zprofile:# Set the precmd() hook to our custom functionprecmd() {buildColorPrompt;}