Chris Padilla/Blog
My passion project! Posts spanning music, art, software, books, and more.
- Converting your data to JSON
- Passing the ID as a query param
- Comparing between the string representation of the ID and the
ObjectID
data type
David Lynch Beyond Words
Kyle MacLachlan wrote a beautiful piece in memory of David Lynch for The New York Times:
Though my lifelong friend, collaborator and mentor David Lynch was as eloquent as anyone I’d ever met — and a brilliant writer — he was not necessarily a word person...
How could words possibly do justice to an experience like that?
It’s why David was not just a filmmaker: He was a painter, a musician, a sculptor and a visual artist — languageless mediums.
When you are outside language, you are in the realm of feeling, the unconscious, waves. That was David’s world. Because there’s room for other people — as the listeners, the audience, the other end of the line — to bring some of themselves.
To David, what you thought mattered, too.
Flow Over Skill
I'm dumbfounded by how there is no correlation between how skilled you are and how much enrichment you get out of practicing an art form.
I spent years in strict training to achieve a certain level of performance ability in music, under an assumption that fulfillment comes from mastery. And don't get me wrong — there is a certain freedom in being able to smoothly skate across an instrument.
But it's not a requirement. And the joy can come from day 1.
The real source is flow. There are plenty reasons to do creative work, but I'd say most of us find the magic in those moments where time slips away.
There are several ingredients to reaching that state. When it comes to ability, though, the key lever is how well the task in front of you matches your skill level.
Is it challenging enough where you're doing a bit of reaching?
Is it easy enough where you don't feel totally overwhelmed by what you're doing.
That's it. And it's relative.
Saxophone is my most fluent instrument. To achieve flow, I would have to be working on a new piece with significant technical and expressive challenges to get there. But when I'm playing guitar, I find it just by spending time moving between two chords again and again and again.
Especially as we're getting started, we're moved by the product of creative work. Someone's ability as a performer inspires us, or a stunning painting really grabs us. That's great for lighting the spark.
If that's the only source of fuel in the practice, though, there's this resentment of not being at that ability.
Most of the fulfillment has to come from the actual act of doing the thing. Thankfully, a certain level of skill is not required. Just flow.
Star Eyes Chord Melody
Star eyes, flashing eyes in which my hopes rise
Let me show you where my heart lies
Let me prove that it adores
That lovingness of yours
🤩
Enjoying this lovely arrangement with Helen O'Connell & Jimmy Dorsey.
Crystal Ocean
Repetition and Meditation
A big reason I still play instruments is for how genuinely soothing it is.
When learning a technique or a piece, it's unavoidable: There are some things you'll just have to play at least several hundred times. Beginners tend to groan at that, and can get discouraged. When you commit to learning an instrument, you're signing up for a lifetime of repetition.
But I've come to like it. Repetition becomes something like prayer. Something gentle to keep your mind centered around something while the subconscious takes care of cleanup duty.
Or, for the secular, it's akin to the benefits of walking throughout the day. If you're not musically inclined, walking gets you pretty similar benefits. Just one foot in front of the other again and again. Connecting with something beautiful — in this case, nature.
For me, though, I like having a little tune learned by the time I make it home.
Deeply Partial Zod Schemas
It's not uncommon to set up a schema with nested properties. In Zod, it could look something like this:
export const userSchema = z.object({
_id: z.string(),
profile: UserProfileSchema,
email: z.array(UserEmailSchema),
calculated: CalculatedUserSchema.optional(),
system: SystemUserSchema.optional()
});
const userProfileSchema = z.object({
firstName: z.string().min(2).trim(),
lastName: z.string().min(2).trim(),
image: z.string().optional()
});
// etc...
This is great for verifying a type has all the required properties. It gets tricky when I want to set all the values as optional, as I might in a $set
object for MongoDB.
Previous versions of Zod had a method deepPartial
that handled just that. It's since been deprecated, but no library replacement has been provided.
In the meantime, you can pull in the original logic into your project to implement the previous logic. It's handily available on this GitHub thread.
Writing For
From Jeremy Keith's What the world needs:
If we’re going to be hardnosed about this, then the world doesn’t need any more books. The world doesn’t need any more music. The world doesn’t need art. Heck, the world doesn’t need us at all.
So don’t publish for the world.
When I write something here on my website, I’m not thinking about the world reading it. That would be paralyzing...
I’m writing for myself. I write to figure out what I think. I also publish mostly for myself—a public archive for future me. But if what I publish just happens to connect with one other person, I’m glad.
Just came across this from earlier in March and forgot that I 1.) already read it and 2.) got great inspiration from it. It's an especially hard problem when worrying about being original on the entire internet. But, as Jeremy points out earlier in the post, you don't have to be original.
Smoother MongoDB ObjectID Handling in Web Applications
Documents in MongoDB automatically generate a unique key on the _id
field. The value is an ObjectId
, a byte data type that is very lightweight. (More details in the docs.)
When querying your DB, you'll be returned an ObjectID
data type. There are several scenarios in a web application where that can become cumbersome:
To navigate around it, you can project the value to a string any time you query the db.
Here's an initial example of querying a collection in an API method:
export async function getPeople(query = {}): Promise<Person[]> {
const client = await clientPromise;
const collection = client.db('your-db').collection('people');
const people = await collection
.find<People>(query)
.toArray();
return people;
}
To convert the _id
value, we'll create an aggregation step to make the conversion with the $toString
operator
const addFieldAggregation = {
$addFields: {
_id: { $toString: '$_id' },
}
};
Now, when querying from your application, you can convert the string value back to an ObjectId
to query the intended document. I'll just convert our query to an aggregation to accomplish this:
import { ObjectId } from 'mongodb';
export async function getPeople(query = {}): Promise<Person[]> {
const client = await clientPromise;
const collection = client.db('your-db').collection('people');
const person = (await collection
.aggregate([
{
$match: query,
},
addFieldAggregation
])
.toArray()) as Person[];
return person;
}
Voilà!
Pace Layers
I've just been introduced to the idea of Pace Layering via Chris Coyier:
...If you feel frustration at how quickly or slowly a particular technology moves, are you considering its place within the layers? Perhaps that speed is because it is part of a system that pressures it to be that way or it being that way is beneficial to the system as a whole.
Amazing to think how transferable it is to other domains. And to have acceptance of the fact that some things are meant to move quickly, others more slowly. The case for government vs commerce in Steward Brand's original case for this feels perpetually timely.
This compliments well with a bit of advice from Derek Sivers to focus on what doesn't change:
Instead, forget predicting, and focus on what doesn’t change. Just like we know there will be gravity, and water will be wet, we know some things stay the same.
People always love a memorable melody. You can’t know what instrumentation or production style will be in fashion. So focus on the craft of making great melodies...
Instead of predicting the future, focus your time and energy on the fundamentals. The unpredictable changes around them are just the details.
Moonlight In Vermont
Telegraph cables, they sing down the highway,
And travel each bend in the road~
No recording more magical than Louis and Ella.
Mountain Bird
Stewart Copeland Composing for Spryo
Well this is delightful!
"I look for how to make those inner complexities more complex, and have deeper sublayers and things that don't really get you the first time, but the 16th time so it can stand repeated listening."
So much to love here. "They pay me for this!"
Handling Dot Notation in MongoDB
There's quite a dance that needs to happen when sending data to a document in MongoDB.
Say that your document takes this shape:
import { z } from 'zod';
const userSchema = z.object({
_id: z.string(),
profile: UserProfileSchema,
email: z.array(UserEmailSchema),
calculated: CalculatedUserSchema.optional(),
system: SystemUserSchema.optional()
});
const userProfileSchema = z.object({
firstName: z.string().min(2).trim(),
lastName: z.string().min(2).trim(),
image: z.string().optional()
});
const userEmailSchema = z.object({
address: z.string().email(),
verified: z.boolean().default(false)
});
// etc...
Note that there is an email
field with an array of objects.
If I wanted to update the address of the first email object in that array, my path object would look like this:
const patch = {
'email.0.address': "hey@chris.com",
}
Here's what you get back from dirtyFields
when you're using a form library on the client such as react-hook-form:
{
email: [
{
address: address,
}
]
}
That would essential replace the entire email field in the db.
There are a few steps to take to handle this:
First, let's pull in a library to handle converting the object to dot notation:
import { dot } from 'dot-object';
const dirtyFieldsDotNotation = dot(dirtyFields);
// {
// "email[0].address": true
// }
Then, we can pass in the actual form value to the results object:
const updatedValues = dirtyFieldsKeys.reduce(
(acc: Record<string, any>, key: string) => {
const regex = new RegExp(/\[|(\]\.)/, 'g');
const parsedKey = key.replaceAll(regex, '.');
acc[parsedKey] = get(parsedUpdatedValues, key);
return acc;
},
{}
);
// {
// "email.0.address": hi@chris.net
// }
Here, I've added a step to replace all angle brackets []
with a period .
to conform with the expected array access syntax for mongo.
With that, our object is now safe to send to our api and pass to our patch call to Mongo:
const client = await clientPromise;
const collection = client.db('project').collection('users');
const result = await collection.updateOne(
{ _id: id },
{ $set: patch },
{ upsert: true }
);
Lady Be Good
All dressed up with no place to go.
Trying out some Gershwin chord melody! A bit of a slower take on the original.