Filtered by JavaScript

Reset

get in JavaScript is the same as property in Python

February 13, 2025
0 comments Python, JavaScript

Almost embarrassing that I didn't realize that it's the same thing!


class MyClass {
  get something() {
  }
}

is the same as Python's property decorator:


class MyClass
    @property
    def something:

They both make an attribute on a class automatically "callable".
These two are doing the same functionality:


class Foo {
  get greeting() {
    return "hello";
  }
  place() {
    return "world";
  }
}

const f = new Foo();
console.log(f.greeting, f.place());
// prints 'hello world'

and


class Foo:
    @property
    def greeting(self):
        return "hello"

    def place(self):
        return "world"

f = Foo()
print(f.greeting, f.place())
# prints 'hello word'

How to send custom headers in a loader in react-router v7

February 7, 2025
0 comments React, JavaScript

tl;dr; Use data() in your loader function and make your headers function pass it on to get headers be dependent on what's happening in the loader function.

I recently rewrote the front end of this website from Remix to react-router v7. A route is a page, which can be something like /about or have a parameter in it like /blog/:slug.

The way react-router v7 (the "framework mode") works is that your route looks like this:


import type { Route } from "./+types/post"

export async function loader({ params }: Route.LoaderArgs) {
  const post = await fetchPost(params.slug)
  return { post }
}

export default function Component({loaderData}: Route.ComponentProps) {
  return <h1>{loaderData.post.title}</h1>
}

So good for so far. But suppose you want this page to have a certain header, depending on the value of the post object. To set headers, you have to add an exported function called, surprise surprise; headers. For example:

Truncated! Read the rest by clicking the link below.

TypeScript enums without enums

January 29, 2025
0 comments JavaScript, TypeScript

My colleague @mattcosta7 demonstrated something that feels obvious in hindsight.

Instead of enums, use a regular object. So instead of


enum State {
  SOLID,
  LIQUID,
  GAS,
}

(playground here - note how "complex" the transpiled JavaScript becomes)

...use an object. Objects have the advantage that when the TypeScript is converted to JavaScript, it looks pretty much identical. TypeScript 5.8 makes it possible to disallow "non-erasable syntax" which means you can set up your tsconfig.json to avoid enum.

The alternative is an object. It's a bit more verbose but it has advantages:


const State = {
  SOLID: "solid",
  LIQUID: "liquid",
  GAS: "gas"
} as const

type State = typeof State[keyof typeof State]

(playground here - note how simple the transpiled JavaScript is)

In the above code, if you hover the mouse over State it'll say

'solid' | 'liquid' | 'gas'

Truncated! Read the rest by clicking the link below.

Run TypeScript in Node without extensions

December 10, 2024
0 comments Node, JavaScript

A couple of months ago I wrote about "Node watch mode and TypeScript" which suggests using the @swc-node/register package to be able to run node on .ts file without first converting it to .js using tsc.

In Node 22, you don't even need @swc-node/register. You can use --experimental-strip-types instead. (Note the prefix "experimental"). See release notes here.

Imagine a script like this:


// example.ts

function c2f(c: number) {
  return (c * 9) / 5 + 32;
}
console.log(c2f(123));

you can execute it directly in Node v22 using:


❯ node --experimental-strip-types --no-warnings example.ts
253.4

Truncated! Read the rest by clicking the link below.

An ideal pattern to combine React Router with TanStack Query

November 18, 2024
1 comment React, JavaScript

I'm writing this blog post from an admin interface I built, which is a web app frontend for the backend behind peterbe.com. It's built as a single-page app in Vite, with React.
Vite, unlike frameworks like Remix or Next, doesn't come with its own routing. You have to add that yourself. I added React Router. Another thing you have to do yourself is a way to load remote data into the app for display and for manipulation. This is done as XHR requests happen on the client side. For that, I chose TanStack Query. If you haven't used it but used React, it's sugar for this type of code:


// DON'T DO THIS. USE TANSTACK QUERY

const [stuff, setStuff] = useState(null)
const [error, setError] = useState(null)
useEffect(() => {
  fetch('/api/some/thing')
    .then(r => r.json())
    .then(data => setStuff(data)
    .catch(err => setError(err))
}, [])

Truncated! Read the rest by clicking the link below.

Object.keys to return the known strings of an object in TypeScript

October 25, 2024
0 comments JavaScript

This one always confused me but by blogging about it, hopefully, it will stick.

This does NOT work in TypeScript:


const person = {
  firstName: "peter",
  lastName: "bengtsson",
  state: "happy"
}

const keys = Object.keys(person)
const randomKey = keys[Math.floor(Math.random() * keys.length)];
const value = person[randomKey]

It works in JavaScript, but in TypeScript you get an error on the last line (from the person[randomKey]):

Truncated! Read the rest by clicking the link below.

How I make my Vite dev server experience faster

October 22, 2024
0 comments React, Node, JavaScript

I have a web app that operates as a SPA (Single Page App). It's built on regular Vite + React + TypeScript. In production you just host the built static assets, but in development (for hot module reloading and stuff) I use the built-in dev server in Vite. This is what you get when you type vite without any other command line arguments.

But here's what happens, you're in the terminal and you type npm run dev and hit Enter. Then, using your trackpad or keyboard shortcuts you switch over to a browser tab and go to http://localhost:5173/. When you get there to the first request, Vite starts at the entry point, which is src/main.tsx and from there, it looks at its imports and starts transpiling the files needed. You can see what happens with vite --debug transform.

With debug:

Truncated! Read the rest by clicking the link below.

How to extend a function in TypeScript without repeating the signature types

October 16, 2024
0 comments JavaScript

Suppose you have a function, written in TypeScript, that is fine and complete. Now you want to write a function that works like that one but with just some slightly more parameters and other differences. It's not too different from a decorator function.

Extending the list of parameters

Let's imagine that you already have this function:


type Operation = "sum" | "sub" | "mul" | "div"

function calculator(a: number, b: number, op: Operation) {
  if (op === "sum") return a + b
  if (op === "sub") return a - b
  if (op === "mul") return a * b
  if (op === "div") return a / b
  throw new Error(op)
}

And this could, for the sake of argument, be in a different file and/or possibly outside your control. What you now want to do is write a new function that takes those same arguments, plus one more. And importantly, you don't want to have to spell out all the arguments one more time.

First, the WRONG way to solve this:


import { calculator } from './calculator' // The code in the snippet above

type Operation = "sum" | "sub" | "mul" | "div"

function doubleCalculator(a: number, b: number, op: Operation, c: number) {
  return calculator(calculator(a, b, op), c, op)
}

console.log(calculator(1, 2, "sum")) // 3
console.log(doubleCalculator(1, 2, "sum", 10)) // 13

Technically, it works, but you had to repeat the calculator function's signature.

Truncated! Read the rest by clicking the link below.

Trying out the new Bun "Compile to bytecode"

October 15, 2024
0 comments Bun, JavaScript

Bun 1.1.30 came out last week. What got me intrigued is this new option to bun build which is --bytecode. With it you can create an executable, supposedly compiled partially to bytecode which means it can start even faster.

I tried it on my hylite CLI which is a CLI, built with Bun, but works in all versions of Node, that can syntax highlight code to HTML on the command line. Here's what I did:

Truncated! Read the rest by clicking the link below.

How to handle success and failure in @tanstack/react-query useQuery hook

September 16, 2024
0 comments React, JavaScript

What @tanstack/react-query is is a fancy way of fetching data, on the client, in a React app.

Simplified primer by example; instead of...


function MyComponent() {
  const [userInfo, setUserInfo] = useState(null)
  useEffect(() => {
    fetch('/api/user/info')
    .then(response => response.json())
    .then(data => {
      setUserInfo(data)
    })
  }, [])

  return <div>Username: {userInfo ? userInfo.user_name : <em>not yet known</em>}</div>
}

Truncated! Read the rest by clicking the link below.

Previous page
Next page