const env_var = process.env.MY_ENV_VAR ?? throw new Error("MY_ENV_VAR is not set");---
I disagree that erroring out when the app doesn't have ALL the data is the best course of action. I imagine it depends a bit on the domain, but for most apps I've worked on it's better to show someone partial or empty data than an error.
Often the decision of what to do when the data is missing is best left up the the display component. "Don't show this div if string is empty", or show placeholder value.
---
Flip side, when writing an under the hood function, it often doesn't matter if the data is empty or not.
If I'm aggregating a list of fooBars, do I care if fooBarDisplayName is empty or not? When I'm writing tests and building test-data, needing to add a value for each string field is cumbersome.
Sometimes a field really really matters and should throw (an empty string ID is bad), but those are the exception and not the rule.
I learned from a friend to use Zod to check for process.env. I refined it a bit and got:
```
const EnvSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'staging']),
DATABASE_URL: z.string(),
POSTHOG_KEY: z.string(),
});export type AlertDownEnv = z.infer<typeof EnvSchema>;
export function getEnvironments(env: Record<string, string>): AlertDownEnv { return EnvSchema.parse(env); }
```
Then you can:
```
const env = getEnvironments(process.env);
```
`env` will be fully typed!
Definitely, I need to do some improvements in my frontend logic!
Consider the author’s proposed alternative to ‘process.env.MY_ENV_VAR ?? “”’:
if (process.env.MY_ENV_VAR === undefined) {
throw new Error("MY_ENV_VAR is not set")
}
That’s 3 lines and can’t be in expression position.There’s a terser way: define an ‘unwrap’ function, used like ‘unwrap(process.env.MY_ENV_VAR)’. But it’s still verbose and doesn’t compose (Rust’s ‘unwrap’ is also criticized for its verbosity).
TypeScript’s ‘!’ would work, except that operator assumes the type is non-null, i.e. it’s (yet another TypeScript coercion that) isn’t actually checked at runtime so is discouraged. Swift and Kotlin even have a similar operator that is checked. At least it’s just syntax so easy to lint…
It's funny you bring this up because people opposed to `.unwrap()` usually mention methods like `.unwrap_or` as a "better" alternative, and that's exactly the equivalent of `??` in Rust.
I may not understand.
<input type=“text” defaultValue={user.email ?? “”}>
The user is an entity from the DB, where the email field is nullable, which makes perfect sense. The input component only accepts a string for the defaultValue prop. So you coalesce the possible null to a string.
```ts user?.name ?? "" ```
The issue isn't the nullish coalescing, but trying to treat a `string | null` as a string and just giving it a non-sense value you hope you'll never use.
You could have the same issue with `if` or `user?.name!`.
Basically seems the issue is the `""`. Maybe it can be `null` and it should be `NA`, or maybe it shouldn't be `null` and should have been handled upstream.
> By doing this, you're opening up for the possibility of showing a UI where the name is "". Is that really a valid state for the UI?
But as a user, if I get a white screen of death instead of your program saying “Hi, , you have 3 videos on your watchlist” I am going to flip out.
Programmers know this so they do that so that something irrelevant like my name doesn’t prevent me from actually streaming my movies.
Don’t listen to those opinionated purists that don’t like certain styles for some reason (probably because they didn’t have that operator when growing up and think it’s a hack)
Is this a kink? You like being on call?
You think your performance review is going to be better because you fixed a fire over a holiday weekend or will it be worse when the post mortem said it crashed because you didn’t handle the event bus failing to return firstName