<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Damilola Emmanuel Olowookere</title>
    <description>The latest articles on DEV Community by Damilola Emmanuel Olowookere (@damms005).</description>
    <link>https://dev.to/damms005</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F189635%2F751f881f-dbf5-43ed-9a3b-b5092fe0e762.jpeg</url>
      <title>DEV Community: Damilola Emmanuel Olowookere</title>
      <link>https://dev.to/damms005</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/damms005"/>
    <language>en</language>
    <item>
      <title>Laravel Starter Kits: Which One Should You Choose?</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Thu, 30 Oct 2025 10:01:21 +0000</pubDate>
      <link>https://dev.to/damms005/laravel-starter-kits-which-one-should-you-choose-3j8b</link>
      <guid>https://dev.to/damms005/laravel-starter-kits-which-one-should-you-choose-3j8b</guid>
      <description>&lt;p&gt;If you are starting a new Laravel project righ now, you're immediately faced with a choice: &lt;strong&gt;React, Vue, or Livewire?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All three starter kits give you authentication scaffolding out-of-the-box, but they take very different approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Quick Decision Matrix
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose React/Vue if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want a modern SPA experience&lt;/li&gt;
&lt;li&gt;Your team has JS framework expertise&lt;/li&gt;
&lt;li&gt;You need rich component ecosystems (Shadcn, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose Livewire if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You prefer staying in PHP&lt;/li&gt;
&lt;li&gt;You want faster prototyping&lt;/li&gt;
&lt;li&gt;Your team is comfortable with Blade&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  React vs Vue?
&lt;/h2&gt;

&lt;p&gt;Both use Inertia.js, TypeScript, Tailwind, and include Shadcn components.&lt;/p&gt;

&lt;p&gt;The difference? &lt;strong&gt;Team preference.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React: Larger ecosystem, steeper learning curve&lt;/li&gt;
&lt;li&gt;Vue: More approachable, especially Vue 3's Composition API&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Want the Deep Dive?
&lt;/h2&gt;

&lt;p&gt;I've written a complete breakdown covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code examples for each approach&lt;/li&gt;
&lt;li&gt;When to use Inertia vs Livewire&lt;/li&gt;
&lt;li&gt;Quick start commands for all three&lt;/li&gt;
&lt;li&gt;Project structure walkthroughs&lt;/li&gt;
&lt;li&gt;How Livewire's new JS APIs compete with React/Vue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://damms005.dev/articles/laravel-12-starter-kits-choosing-react-vue-or-livewire-27" rel="noopener noreferrer"&gt;Read the full article on my blog →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Which starter kit did you choose for your last Laravel project? Drop a comment below! 👇&lt;/p&gt;

</description>
      <category>vue</category>
      <category>react</category>
      <category>laravel</category>
    </item>
    <item>
      <title>AI deserves your job</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Sun, 31 Mar 2024 22:56:41 +0000</pubDate>
      <link>https://dev.to/damms005/ai-deserves-your-job-582d</link>
      <guid>https://dev.to/damms005/ai-deserves-your-job-582d</guid>
      <description>&lt;h2&gt;
  
  
  In the Beginning...
&lt;/h2&gt;

&lt;p&gt;OpenAI released ChatGPT in November of 2022. This arguably marked the beginning of mainstream adoption of Artificial Intelligence (AI) in our world as we know it.&lt;/p&gt;

&lt;p&gt;It is now well over a year since this event happened, and there are lots of persons whose response to date is to panic into a &lt;a href="https://en.wikipedia.org/wiki/Blue_screen_of_death"&gt;BSOD&lt;/a&gt; with the error message "AI is taking our jobs".&lt;/p&gt;

&lt;h2&gt;
  
  
  The Thieves Parallel
&lt;/h2&gt;

&lt;p&gt;Interestingly, this behavioral response resonated with my childhood. Some years back growing up, I lived with my parents in a middle-class enclave in Nigeria. It was commonplace for armed thieves to come to "operate" in our area or surrounding communities. However, some daredevil-level thieves communicate their visitation ahead of time. They would write ahead of time that they were coming to a particular area to operate. Yes, you read that right. They will write in plain black-and-white that they were coming to some named place for "operation", and sneakily paste the notice on paper on a community gate or some other conspicuous place. I have a theory for such a bold move, but I digress.&lt;/p&gt;

&lt;p&gt;However, it was interesting how our local chiefs handled such messages back then. Usually, when they receive such message, they rally the men in the area, arm them, and establish a schedule of local vigilante operations. Temporary vigilante groups comprising heads of local families will then take turns to keep watch at nights for agreed periods of time. I was old enough to recall how my mom stayed awake at nights my dad's group watch the night.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Weak Response
&lt;/h2&gt;

&lt;p&gt;We can draw similarities between "AI is taking our jobs" and the thieves that announced to come operate at our area in the experience I shared above. &lt;em&gt;If you are ever afraid of AI taking your job, then AI does indeed deserve to take your job.&lt;/em&gt; In my opinion, there is an abysmal level of "skill issue" and resistance to change that will make an individual think that an automated system could render them redundant. This will remain true for as long as we are yet to record some significant level of sentience in AI tech. And that honestly doesn't sound like a panic-worthy problem.&lt;/p&gt;

&lt;p&gt;In the experiences I explained previously, such response is similar to one in which our local chiefs back then folded their hands instead, and the local community joining them in accepting fate and resigning to some unavoidable doom.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Stronger Response
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y5wq8gg2ry2jdwoik21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y5wq8gg2ry2jdwoik21.png" alt="Embrace, extend, and extinguish" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is much better to give a stronger response to this fear. &lt;em&gt;Why not &lt;a href="https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish"&gt;Embrace, Extend, and Extinguish (EEE)&lt;/a&gt; your fear of AI?&lt;/em&gt; Embrace the fact that AI is here to stay. Leverage it to "extend" yourself, i.e. be able to do what you previously were unable to do before your knowledge of AI. Then extinguish the fear completely.&lt;/p&gt;

&lt;p&gt;You need to find your own EEE strategy. For some, it may be upskilling. For others, it may be to intelligently apply the knowledge of AI to one's routines and workflows. Just do anything better than gloating over AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;AI is actually powered by some code written by guess who? Correct! Humans like you! Look at the bigger picture of what you can do to, and with AI. Think of the million and one ways AI can make you more efficient and much better. &lt;strong&gt;If AI takes your job, you gave it away.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;PS: Don't forget to share it with your peeps. Also, please share your thoughts in the comments section below.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Auto-loading databases in VS Code using DevDb</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Tue, 09 Jan 2024 11:23:46 +0000</pubDate>
      <link>https://dev.to/damms005/auto-loading-databases-in-vs-code-using-devdb-38f</link>
      <guid>https://dev.to/damms005/auto-loading-databases-in-vs-code-using-devdb-38f</guid>
      <description>&lt;p&gt;There is a non-zero chance that if you use VS Code, you are using the integrated terminal rather than the system terminal/cli app. This is because we love and appreciate the advantages that such an integration brings, e.g.:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less context-switching&lt;/strong&gt;. There is less distraction especially when you want to really focus on the task at hand. The lesser you have to switch from one app to another, the better the DX (Developer Experience). Switching to-and-from apps is obviously not good when trying to focus on a database related coding/dev task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contextual integration&lt;/strong&gt;. Another advantage is that VS Code is able to provide integrations related to the currently opened workspace. e.g. The &lt;code&gt;cwd&lt;/code&gt; defaults to the project root, you can click on links to files from the terminal to open it in the IDE, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above are just a few of the advantages when VS Code provides integrations for tools.&lt;/p&gt;

&lt;p&gt;Now, why can't we have the same experience when working with databases? Why do we have to configure our database credentials in our project (e.g. &lt;code&gt;.env&lt;/code&gt; in Laravel) &lt;em&gt;and&lt;/em&gt; also configure it in another database GUI desktop app? Why do we have to switch from VS Code to TablePlus/phpmyadmin/whatever-your-favourite-database-desktop-app-is? Ask no more, because you can now use &lt;a href="https://marketplace.visualstudio.com/items?itemName=damms005.devdb"&gt;DevDb&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;DevDb is a framework- and language-agnostic VS Code extension that auto-loads your database without the need for configuring database connection separately from what you already configured in your application code. It currently &lt;a href="https://github.com/damms005/devdb-vscode/#supported-databases"&gt;supports SQL, MySQL, and Postgres databases&lt;/a&gt;, with plans to support more databases in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DevDb features&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It auto-loads your database and shows your data right inside VS Code. In a Laravel project, this is done by processing some files like &lt;code&gt;config/database.php&lt;/code&gt;, &lt;code&gt;docker-compose.yml&lt;/code&gt;, and &lt;code&gt;.env&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If it cannot auto-load your database (yet 😉), you simply provide a &lt;a href="https://github.com/damms005/devdb-vscode/#2-config-based-database-loading"&gt;&lt;code&gt;.devdbrc&lt;/code&gt; file&lt;/a&gt; in the root of your application. This is why you can use it in any framework and any programming language&lt;/li&gt;
&lt;li&gt;In any tool, framework, or programming language, you can open any table using the provided context menu feature. The example below is from a Node JS project:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BhdNUzMX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/damms005/devdb-vscode/raw/main/resources/screenshots/context-menu-contribution.png" alt="image" width="800" height="525"&gt;
&lt;/li&gt;
&lt;li&gt;It provides &lt;a href="https://code.visualstudio.com/blogs/2017/02/12/code-lens-roundup"&gt;Code Lens&lt;/a&gt; in Laravel Eloquent models
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CtjASzya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/damms005/devdb-vscode/raw/main/resources/screenshots/laravel-code-lens.png" alt="image" width="800" height="507"&gt;
&lt;/li&gt;
&lt;li&gt;It has a nice and intuitive interface, and makes navigation a bliss!&lt;/li&gt;
&lt;li&gt;It has dark mode! I mean, why not? 😜&lt;/li&gt;
&lt;li&gt;When you're not in a hurry and idle, it tells actual dad jokes:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FYe8Zyys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/damms005/devdb-vscode/raw/main/resources/screenshots/devdb-dad-joke.png" alt="image" width="800" height="389"&gt;
&lt;/li&gt;
&lt;li&gt;And what's more? It's Open Source! You can tinker with &lt;a href="https://github.com/damms005/devdb-vscode/"&gt;the source code&lt;/a&gt; and PR anything you're missing as long as &lt;a href="https://github.com/damms005/devdb-vscode/blob/main/CONTRIBUTING.md#procedure"&gt;it's okay 😊&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can start using DevDb right now. Check it out in &lt;a href="https://marketplace.visualstudio.com/items?itemName=damms005.devdb"&gt;the VS Code marketplace&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Composer's Dev Environment: A Beginners' Guide to Dependency Management in PHP</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Fri, 23 Jun 2023 12:45:38 +0000</pubDate>
      <link>https://dev.to/damms005/understanding-composers-dev-environment-a-beginners-guide-to-dependency-management-in-php-4l1o</link>
      <guid>https://dev.to/damms005/understanding-composers-dev-environment-a-beginners-guide-to-dependency-management-in-php-4l1o</guid>
      <description>&lt;p&gt;Let's imagine for a moment that you're building your dream house. Before you can start, you'll need a lot of different tools and materials. Now, wouldn't it be nice if you could write down a list of everything you need and someone magically brings it all to you? This is precisely the purpose of Composer in the PHP world. Do you know JavaScript's NPM? Yes, it does the same. essentially.&lt;/p&gt;

&lt;p&gt;Composer is a tool that manages dependencies in PHP projects. Think of it as a helper who takes care of the heavy lifting when it comes to finding, downloading, and setting up the libraries your application needs to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The composer.json File: Your Project's Shopping List
&lt;/h2&gt;

&lt;p&gt;So, how does Composer know what your project needs? The answer lies in a file named &lt;code&gt;composer.json&lt;/code&gt;. This file, typically located at the root of your project, is like a shopping list for your project's dependencies.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;composer.json&lt;/code&gt; file, there are two important sections to be aware of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;require:&lt;/code&gt; This section lists the libraries and packages that your application needs to function correctly. These are the dependencies that are absolutely necessary for your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;require-dev:&lt;/code&gt; This section, on the other hand, lists the dependencies that you need during development. These typically include tools like unit testing libraries and debugging tools. They're not necessary for your application to run, but they make the development process much smoother.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Does Composer Know the Development Environment?
&lt;/h2&gt;

&lt;p&gt;When installing or updating the packages, Composer checks the environment by looking at the &lt;code&gt;--dev&lt;/code&gt; or &lt;code&gt;--no-dev&lt;/code&gt; flag provided in the command. By default, Composer assumes the development environment and installs both &lt;code&gt;require&lt;/code&gt; and &lt;code&gt;require-dev&lt;/code&gt; dependencies.&lt;/p&gt;

&lt;p&gt;To install only the production dependencies (the ones listed in &lt;code&gt;require&lt;/code&gt;), you need to specify the &lt;code&gt;--no-dev&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;composer&lt;/span&gt; install --no-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, if you want to install both production and development dependencies, you can use the &lt;code&gt;--dev&lt;/code&gt; flag or simply run the command without any flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;composer&lt;/span&gt; install --dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Should You Specify the Appropriate Environment Flag?
&lt;/h2&gt;

&lt;p&gt;You asked? I knew you would. There are a few reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimizing Dependencies&lt;/strong&gt;: Specifying the correct environment flag ensures that your project has the necessary dependencies for the given environment. This prevents unnecessary packages from being installed in production, leading to a leaner and faster application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reducing Resource Usage&lt;/strong&gt;: Development dependencies often include packages that consume system resources, such as memory and CPU. By avoiding their installation in production, you can save resources and improve the performance of your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Limiting the installed packages to the ones needed for the production environment can reduce the potential attack surface. This makes it harder for attackers to exploit potential vulnerabilities in the development packages that are not needed in production.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding how Composer knows the development environment and manages the dependencies is essential for PHP developers. Composer doesn't "know" your environment by itself. Instead, you provide this information through the use of flags when running Composer commands. By specifying the appropriate environment flag, you can optimize your application's performance, reduce resource usage, and enhance its security.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>PHP's First-Class Callable Syntax</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Fri, 23 Jun 2023 01:43:47 +0000</pubDate>
      <link>https://dev.to/damms005/phps-first-class-callable-syntax-1kjl</link>
      <guid>https://dev.to/damms005/phps-first-class-callable-syntax-1kjl</guid>
      <description>&lt;p&gt;This awesomess introduced in PHP 8.1 does not get the attention it deserves, IMO. I intend to use this post to show how cool it is!&lt;/p&gt;

&lt;p&gt;PHP 8.1 introduces a more streamlined way to create callable functions, called the "first-class callable syntax".  Let's dive in a littel bit into this syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little backtrack...
&lt;/h2&gt;

&lt;p&gt;Previously, we use &lt;code&gt;Closure::fromCallable&lt;/code&gt; to turn a function or method into a callable object. This function takes in a PHP callable (which could be a function name, a method, or even an anonymous function) and spits out a Closure object. A typical example would be converting the &lt;code&gt;strtoupper&lt;/code&gt; function into a callable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$callable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Closure&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;fromCallable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'strtoupper'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Outputs 'FOO'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method gets the job done, but isn't it a bit too verbose? Or perhaps we can make it a tad better. PHP 8.1's new syntax seeks to eliminate this extra clutter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new sauce 🪄
&lt;/h2&gt;

&lt;p&gt;With the new syntax, you simply call the function or method followed by ellipsis (&lt;code&gt;...&lt;/code&gt;) to create a first-class callable. That way, you can create a callable from the &lt;code&gt;strtoupper&lt;/code&gt; function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$callable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Outputs 'FOO'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I will say &lt;em&gt;that&lt;/em&gt; is so much more cleaner! You can create first-class callables from function names, class methods, static methods, and anonymous functions. Just remember that the ellipsis (...) isn't a placeholder for any specific parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hold up now, soldier!
&lt;/h2&gt;

&lt;p&gt;Here's where you need to be careful though. While the new syntax seems to hint at partial function application (the idea that you can fix a number of arguments to a function), PHP doesn't currently support it. So, attempting to pass any parameters to the callable would result in a syntax error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Assume $text is a defined variable&lt;/span&gt;

&lt;span class="nv"&gt;$callable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str_contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// A syntax error, as partial function application is not supported.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other Considerations
&lt;/h2&gt;

&lt;p&gt;The ellipsis (&lt;code&gt;...&lt;/code&gt;) have other uses as well. One is in creating 'variadic functions', or functions that can take an indefinite number of arguments. The ellipsis also comes in handy when we want to 'spread' or distribute elements of an array or object to a function.&lt;/p&gt;

&lt;p&gt;However, even with the introduction of first-class callables using the ellipsis, these existing uses of the ellipsis in PHP remain unchanged. So, there's no need to worry about the new callable syntax causing any disruptions to your previous work.&lt;/p&gt;

&lt;p&gt;Also note that you can't use the syntax to instantiate new objects with the &lt;code&gt;new&lt;/code&gt; keyword, or to declare null-safe methods or attributes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;p&gt;One cool aspect of first-class callables is that they carry the scope of the location where they were created. This means a first-class callable can access private methods, as long as it's created within the object's scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compatibility
&lt;/h2&gt;

&lt;p&gt;This feature is new to PHP 8.1 and so can't be used with older versions. If you need to maintain compatibility with older versions, you'll have to stick with &lt;code&gt;Closure::fromCallable&lt;/code&gt;. But if you're using PHP 8.1 or later, you'll surely love the simplicity and efficiency the first-class callable syntax brings to your coding!&lt;/p&gt;

&lt;p&gt;I hope you found this explanation both interesting and informative. You can read more &lt;a href="https://www.php.net/manual/en/functions.first_class_callable_syntax.php"&gt;in the official docs&lt;/a&gt;. The journey of PHP continues, and I can't wait to see where it takes us next. Keep coding, keep learning! &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Laravel migration squashing and use of SQLite in automated testing</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Fri, 17 Sep 2021 22:40:21 +0000</pubDate>
      <link>https://dev.to/damms005/laravel-migration-squashing-and-use-of-sqlite-in-automated-testing-2d5k</link>
      <guid>https://dev.to/damms005/laravel-migration-squashing-and-use-of-sqlite-in-automated-testing-2d5k</guid>
      <description>&lt;p&gt;I recently started taking more conscious efforts of improving the confidence I have in my deployments by writing automated tests.&lt;/p&gt;

&lt;p&gt;However, since the introduction of &lt;a href="https://laravel.com/docs/8.x/migrations#squashing-migrations"&gt;Laravel's  migration squashing&lt;/a&gt;, I have been having a hard time writing tests that use the &lt;a href="https://laravel.com/docs/8.x/database-testing#resetting-the-database-after-each-test"&gt;&lt;code&gt;RefreshDatabase&lt;/code&gt; trait&lt;/a&gt;. This is particularly because my development is typically with MySQL and testing is with SQLite.&lt;/p&gt;

&lt;p&gt;The pains that this new squashing feature brings to sqlite testing is well &lt;a href="https://github.com/laravel/framework/issues?q=is%3Aissue+is%3Aopen+squash"&gt;documented&lt;/a&gt;, and Taylor himself acknowledges this, because he &lt;a href="https://github.com/laravel/framework/issues/35162#issuecomment-725476371"&gt;recommended against using in-memory sqlite db during testing&lt;/a&gt; (btw, in-memory sqlite db is usually the go-to solution for db testing in Laravel.)&lt;/p&gt;

&lt;p&gt;Assuming you have already squashed your migrations into dump file and you have something like your &lt;code&gt;mysql-schema.dump&lt;/code&gt; file, then the way I approach tests that includes migration is to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Convert the &lt;code&gt;mysql-schema.dump&lt;/code&gt; SQL content to SQLite's SQL, and save the file. I typically use &lt;a href="https://github.com/dumblob/mysql2sqlite"&gt;this tool&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mysql2sqlite.sh mysql-schema.dump &amp;gt; converted.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Move the new dump to Laravel's schema dump folder, and ensure to &lt;a href="https://github.com/laravel/framework/issues/36523#issuecomment-795646743"&gt;name it appropriately with the connection name&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When I follow these steps, it is now much more comfortable writing tests that use the &lt;code&gt;RefreshDatabase&lt;/code&gt; trait with SQLite as testing db. For as long as I do not come across a better way to handle this migration-squashing-sqlite-testing thingy, I may end up re-visiting this post. So, it is a note to future self!&lt;/p&gt;

&lt;p&gt;I hope this post saves you a few minutes of debug time. See you in the next 😎&lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
    <item>
      <title>MongoDB, Mongoose, and MongoDB Atlas (Cloud Service)</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Mon, 06 Sep 2021 11:09:25 +0000</pubDate>
      <link>https://dev.to/damms005/mongodb-mongoose-and-mongodb-atlas-cloud-service-36gl</link>
      <guid>https://dev.to/damms005/mongodb-mongoose-and-mongodb-atlas-cloud-service-36gl</guid>
      <description>&lt;p&gt;If you, like me, like short, succinct tech articles (like my previous write-up on &lt;a href="https://dev.to/damms005/javascript-spread-syntax-gotcha-3c8n"&gt;a JS spread syntax gotcha&lt;/a&gt; and &lt;a href="https://dev.to/damms005/practical-use-cases-of-vue-js-mixins-5911"&gt;use cases of VueJs mixins&lt;/a&gt;); and you like daring tech adventures, then you are going to love this piece of The Three &amp;lt; insert-anything-here™️ &amp;gt; - eers.&lt;/p&gt;

&lt;p&gt;IMHO, MongoDB is not just a document store, but one that is great for fast bootstrapping, especially at the ideation stage of a project. This is because at this stage, there may be no concrete decision about db schema, etc.; and things may be changing very fast with respect to db schema.&lt;/p&gt;

&lt;p&gt;I recently used MongoDB in a project; and being my first time of using it in production, I must say it really helped in bootstrapping. This advantage of MongoDB was made more obvious to me this time around because I used it alongside &lt;a href="https://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; in this same project. The overhead I had in swapping things around in PostgreSQL was relatively higher than in MongoDB.&lt;/p&gt;

&lt;p&gt;The part of &lt;a href="https://mongoosejs.com"&gt;Mongoose&lt;/a&gt; in all these is the awesomeness and ease it brings to using Mongoose in NodeJS apps. However, I find that it does not play nice with &lt;a href="https://cloud.mongodb.com"&gt;MongoDB Atlas&lt;/a&gt;, especially that &lt;a href="https://stackoverflow.com/questions/69070246/how-can-local-robo3t-connect-to-a-remote-mongo-db-instance-but-nodejs-fails-wit/69071273"&gt;a weird behaviour is not documented&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Specifically, when you need to use Mongoose to connect to a remote MongoDB Atlas db instance, you must set your &lt;code&gt;authSource&lt;/code&gt; and &lt;code&gt;ssl&lt;/code&gt; connection parameters appropriately, so that you won't &lt;a href="https://stackoverflow.com/a/69071273/1823554"&gt;spend a decade debugging and wiring things up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, there it is. I hope you enjoy this piece. See you in the next one!&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Practical use-cases of Vue.js mixins</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Mon, 30 Aug 2021 13:32:32 +0000</pubDate>
      <link>https://dev.to/damms005/practical-use-cases-of-vue-js-mixins-5911</link>
      <guid>https://dev.to/damms005/practical-use-cases-of-vue-js-mixins-5911</guid>
      <description>&lt;p&gt;I love &lt;a href="https://vuejs.org"&gt;Vue.js&lt;/a&gt;, as I guess you do too (yeah, because you want to read this article). I poured this same love into the reading of the &lt;a href="https://vuejs.org/v2/guide"&gt;official documentation&lt;/a&gt;: a love commensurately reciprocated by the Vue docs team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you can, by all means possible, you should be using &lt;a href="https://learnvue.co/2021/05/explaining-the-new-script-setup-type-in-vue-3-major-takeaways-from-the-rfc/"&gt;Vue 3 in your new projects&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, for some reasons that are beyond the scope of this post (/coughs/ laziness /coughs/) I somehow almost always consciously skip the &lt;a href="https://vuejs.org/v2/guide/mixins.html"&gt;mixins&lt;/a&gt; section. That weird voice in my head always whisper things like "here goes all these unnecessary framework over-complication stuff"&lt;/p&gt;

&lt;p&gt;So, if you are like me, you have been using Vue for a while now, and you absolutely have not used mixins nor considered using it, then these 2 reasons are the advantages I have gained in using mixins in my Vue 2 projects:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. De-congestion of Single File Components (SFCs)&lt;/strong&gt;&lt;br&gt;
When I code SFCs, I like to keep the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; section as lean as possible. I like keeping the cognitive load of parsing my SFCs to the minimum, and mixins help a lot in this regard. Immediate advantages of this practise include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better code organisation&lt;/li&gt;
&lt;li&gt;Perfect for &lt;a href="https://vuejs.org/v2/guide/filters.html"&gt;filters&lt;/a&gt; (for Vue 2)&lt;/li&gt;
&lt;li&gt;Icing on cake: easier modular development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Escape route for better TypeScript support&lt;/strong&gt;&lt;br&gt;
Well, Vue 3 brings better support for TypeScript. For Vue 2, the most optimal TS experience is gotten by setting up &lt;a href="https://vuejs.org/v2/guide/typescript.html#Class-Style-Vue-Components"&gt;Class-Style Components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, with mixins, I can have a &lt;code&gt;.ts&lt;/code&gt; mixin file and do all my Safe Coding™️ there without worrying about limited TS support in SFC files.&lt;/p&gt;

&lt;p&gt;These above are the strongest reasons I have for using mixins in my Vue 2 projects.&lt;/p&gt;

&lt;p&gt;I hope you learned something in this piece, too.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>JavaScript spread syntax gotcha</title>
      <dc:creator>Damilola Emmanuel Olowookere</dc:creator>
      <pubDate>Mon, 30 Aug 2021 07:26:20 +0000</pubDate>
      <link>https://dev.to/damms005/javascript-spread-syntax-gotcha-3c8n</link>
      <guid>https://dev.to/damms005/javascript-spread-syntax-gotcha-3c8n</guid>
      <description>&lt;p&gt;Well, we all like spreads of all kinds. But &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"&gt;this type of spread's&lt;/a&gt; got a gotcha.&lt;/p&gt;

&lt;p&gt;While it may seem obvious, it really did not occur to me until I traced a bug to it.&lt;/p&gt;

&lt;p&gt;Consider a scenario whereby you are keeping a collection of programming/scripting languages. You now defined something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const languages = {
    "interpreted": ['php', 'javascript'],
    "compiled": [
        "java", 
        {"name":"c#","preferred":true},
        "rust"
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you've got yourself a beautiful collection of languages. Suppose you want to send Bob your language collection, and you don't want whatever Bob does to his own copy of this language collection to affect yours, how do you do that?&lt;/p&gt;

&lt;p&gt;Well, for me, as a JavaScript Senior Dev Super-guru™️ that I am, I will spread the butter on the bread, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bobsCopyOfLanguages = {...languages};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, suppose I know that Bob does not like C#; and I do not want Bob to know about my secret affair with Miss C#, so I smartly and swiftly coded in my lie, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bobsCopyOfLanguages.compiled[1].preferred = false;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah. Done and dusted. Now Bob has a Certified True Copy™️ of my Certificate of non-preference for C#. Cool!&lt;/p&gt;

&lt;p&gt;Well, now I've sent &lt;code&gt;bobsCopyOfLanguages&lt;/code&gt; to Bob. Now lemme get on with my own life. I'll start my life by logging my preference for C# and admire the truthiness in my deep love for C#...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(languages.compiled[1].preferred);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and lo and behold, my log shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What, when did#$%!^#&amp;amp;**#...&lt;/p&gt;

&lt;p&gt;Well, curse not.&lt;/p&gt;

&lt;p&gt;This behaviour of Spread Syntax may be obvious to many, but for me, I had to sleep over it to think this through with fresh mind this morning.&lt;/p&gt;

&lt;p&gt;The key here is to not forget that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Objects are passed by reference in JavaScript&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, as long as you have that cleared, then you know that what you "spread" or "copied" to Bob is effectively a copy of your &lt;code&gt;languages&lt;/code&gt; object. However, the nested object is still copied &lt;strong&gt;by reference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, yeah, it is what it is.&lt;/p&gt;

&lt;p&gt;One way I deal with this kind of Truly Copying™️ a light-weight object like this is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bobsCopyOfLanguages = JSON.parse(JSON.stringify(languages));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you like my style of tech writing and learned something today!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;P.S.: confession: C# is not my preferred language.&lt;/p&gt;

&lt;p&gt;P.S.: If you do Vue, yo might be interested in &lt;a href="https://dev.to/damms005/practical-use-cases-of-vue-js-mixins-5911"&gt;my article about the Practical Use-cases of Mixins in Vue 2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
