#22 Creating a job board in Laravel, flatten an object array in Vue, and more

Welcome to the 22nd issue of The VOLT newsletter! Here's a few things from the last couple weeks:

Hey everyone! Sorry it’s been a while, but here’s a few things from the past month or so that caught my attention. Also if you’d like to join a small (but growing) Discord community to learn, share, and collaborate with others, check out The VOLT server at discord.gg/AFDUJdcTcz

Creating a job board in Laravel

I recently released a 7-part free series on YouTube detailing how to build a job board application from scratch in Laravel.

Each part focuses on one isolated piece of the whole application, from seeding the database, to creating the landing page with Tailwind, and even using Cashier with Stripe to accept payments for paid listings.

You can see the first episode here, or click on the title to watch the full series:

My goal when recording this was to make something that both beginners and people more experienced with the framework, would get enjoyment and use out of. I’m planning on releasing follow-up videos to show off things like creating tests, accepting applications, and automated deployment.

If you’d like to view the source code, it’s on GitHub at aschmelyun/laravel-job-board.

Flatten an object array in Vue

When working in Vue it’s not uncommon to deal with large amounts of data coming in from APIs, specifically arrays of objects. Sometimes there’s items in these objects that need to be flattened down into a single value, like the total balance in bank transactions or attendees in outdoor events.

Instead of looping through each object and using a variable and conditionals to count up the flattened value, you can use a few modern JavaScript methods to do it for you:

In the example above, I’m creating an array of objects, each one with a quantity integer and price. If I had a shopping cart component in Vue and wanted to get back a single value for the total amount of the items in the cart, I’d use the return line in a computed property to display that.

How it works is that reduce takes two arguments, a collector (a holder for your final returned value) and the current item in the array this is called on. Inside of the callback method, you can perform actions to manipulate the current total value, and return it back to the parent method. In this case, we’re adding to it the price of the current item multiplied by the quantity.

My (updated) Laravel Docker environment

If you’ve watched or read any of my Docker content, chances are you’ve seen the repo that I’ve maintained for over a year: aschmelyun/docker-compose-laravel.

I still continue to use this as a basis for local Laravel development with Docker without issue, however I kept seeing issues being added regarding permissions errors. Specifically in Linux and Windows (WSL-2) systems. So, I decided to spend a weekend and dig into the issue.

The underlying problem was caused by the files in the mounted volumes being owned by the user/group from the host system. Everything that I did to try to overwrite that ownership from the container didn’t stick. So, I went the opposite way. Using the PHP, Nginx, and Composer containers, I create the same user/group from the host machine on the container at build time. This way, the software running on the container doesn’t encounter any issues when writing to the file system contents in the mounted volume.

There’s a little more work needed in setting this up, specifically you’ll need to create a .env file containing the user and group name(s) that your volume’s files are owned by. In the future, I’ll try and find a way to automate this part, but for now it’s been working beautifully across multiple machines and OS’s. 🥳

Creating a Vue component in a Vue component

Have you ever created a component in Vue, and needed another (smaller) component, but didn’t think it was totally necessary to split it out into its own file? Good news, you don’t have to! Thanks to this tip by Michael Thiessen, you can include a smaller, succinct component in your larger one, directly in the same file.

Here’s what that looks like:

Instead of importing the separate SmallComponent, you can just create it above the main export default call, and use it in the components object!

Today I learned

This helpful hint comes from Ryan Chandler, and was originally a comment on my Laravel Job Board series that I posted above.

Normally I would call the getRouteKeyName() method on a Laravel model to change the route model key binding column. However, you can just use a colon after the model placeholder in a route definition, and pass in the column name! In the example below, I’m using the slug column.

That’s it for now! If you have any questions about the above, or have something you’d like me to check out, please feel free to let me know on Twitter.