Member Since 2 Years Ago

Des Moines, IA

Senior Software Engineer at Vox Media

Experience Points 26,370
Experience Level 6

3,630 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 235
Best Reply Awards 4
Best Reply
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber-token Created with Sketch.


    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.


    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

05 Mar
4 months ago

jplhomer left a reply on Phpunit.xml Not Being Read, Using Variables From .env

@SHANETURNER - I'm running into this exact issue with a fresh install of Laravel 5.8 ?trying to figure out why this is happening. Even starting up bash and running g `phpu triggers the issue.

08 Apr
1 year ago

jplhomer left a reply on Laravel Switches Back To Smtp When There Is A Mailing Task In A Queued Event Listener.

Might sound silly, but have you tried stopping/starting your queue working artisan queue:work after setting the Mailgun credentials in your .env file? Sometimes when I see weird things in my queue workers, it's because they are referencing old code and need to be restarted.

jplhomer left a reply on [Vue Warn]: Error In Render: “TypeError: Cannot Read Property ‘name’ Of Undefined” When Use Deep Object (3 Levels)

@deryck It sounds like your Vue component might be trying to render your input, which references a nested object value, before that object is available.

Since it's coming from an AJAX request, this is solvable by wrapping your form with a v-if="!loading" boolean, and modifying that boolean to be true once your data has loaded:

<div v-if="!loading">
  <input type="text" class="form-control form-control-static" v-model="">
// data object
  property: {},
  loading: false

fetchProperty: function() {
  this.loading = true;
  // ...
  .then(function(response) { = {...};
    this.loading = false;
01 Feb
1 year ago

jplhomer left a reply on Vuex Getters With Multiple State Data Arrays.

Hey @thindery,

I think this is where you might take advantage of a getter's ability to return a method. Per the docs:

getters: {
  // ...
  getDepartmentOrders: (state) => (departmentId, orderType) => {
    return state.orders
    .filter(o => o.departmentId === departmentId)
    .filter(o => o.orderType === orderType)
store.getters.getDepartmentOrders(2, 'late') // -> { id: 2, name: '...', late: true }

Another option I'd recommend is aggregating this data in your landing/dashboard controller to initially serve it to the user - maybe caching it if it's a large query. That way, you can serve up this aggregate chart data at the landing endpoint without worrying about populating the global store with this data which should really be loaded at each department's endpoint.

Good luck!

15 Jan
1 year ago

jplhomer left a reply on Socialite/OAuth & Google Apps?

@zness21 Hey Zac,

It sounds like you're almost there - you just need to take an extra step to get the data you want!

I'd double check that you're indeed requesting the OAuth scopes required to traverse the Google Apps directory stuff:

Once the user has granted access, you'll get a $token variable you can use to make future requests using Google's own PHP SDK:

$user = Socialite::driver('google')->user();
$token = $user->token;

// TODO: Install google/api-client via Composer
$client = new Google_Client();
$client->setApplicationName("My Application");
$service = new Google_Service_Directory($client);
// use $service to access your directory

Google has more docs on their Getting Started guide: More here:

jplhomer left a reply on Processing Resource-Intensive Jobs With Laravel

@cameronscott137 I think you're on the right track with setting up queued, chained jobs. Sounds like the perfect fit for your scenario!

Specifically, if you're worried about resource-intensive jobs, you'll want to leverage queue workers which can be scaled out horizontally as needed. Workers will talk to your Redis server and handle jobs as they come in. I've done something similar for video processing, and Laravel made it pretty easy.

You mentioned SFH - I'd recommend Chris's latest free series Scaling on Forge. He has a video about creating queue workers - might be helpful.


jplhomer left a reply on Very Slow PHPUnit Tests Using PHP7.2 Or PHP7.1.

@mstnorris I'm currently experiencing the same issue! Pulling my hair out, and I've tried so many things: sqlite/mysql, withholding certain tests, trying in-memory vs in-database storage. Tests always hang on the ~25th test for me, and the hanging test takes at least 30 seconds to complete. Skipping a test just causes the next one to hang.

............................                                      28 / 28 (100%)

You should really fix these slow tests (>500ms)...
 1. 36563ms to run Tests\Unit\VacationRequestTest:test_a_request_approved_scope_works
 2. 815ms to run Tests\Feature\CreateVacationRequestTest:test_notification_is_sent_when_vacation_requested

Time: 38.85 seconds, Memory: 296.00MB

OK (28 tests, 53 assertions)

I'm running:

Laravel v5.5.21
macOS High Sierra
PHPUnit 6.5.5

Experiencing the same issue when running it in a Docker container.

18 Nov
1 year ago

jplhomer left a reply on Components/.vue Files Not Formatted/rendered

@splendidkeen haha, no way! That's odd - I would definitely restart your editor if you haven't already. But other than that, I'm out of ideas.

17 Nov
1 year ago

jplhomer left a reply on 500 Server Error With Axios

Yuck. This stuff can be frustrating.

  1. Can you paste in the 500 error you're receiving? This would be available in the Chrome Devtools Network tab (or whatever flavor of browser you're using).
  2. Could you also verify that X-CSRF-TOKEN is a header in the Request being sent (also in the network tab)? This will help us determine whether the logic in bootstrap.js is working correctly.

Good luck.

jplhomer left a reply on Vue-Router Append Tabs Onto URL For Sharing

Check out the children property for Vue Router:

You'll probably end up with something like this:

const router = new VueRouter({
  routes: [
    { path: '/projects/:id', component: Project,
      children: [
          // ProjectFiles will be rendered inside Project's <router-view>
          // when /project/:id/files is matched
          path: 'files',
          component: ProjectFiles
          // Other tabs here

Good luck!

jplhomer left a reply on Components/.vue Files Not Formatted/rendered

This is likely something you'll need to install at an editor level.

I'm sure there are others for Sublime, etc.

jplhomer left a reply on Execute Every Time A Component Is Shown.

What is your current setup? Are you using Vue Router, where mounted won't fire every time it switches between component contexts?

Otherwise, mounted will generally do the trick each time the component is mounted or "displayed" - unless you have the component cached in place.

Another option is to add a watcher for some key value. For example, if you're using activeComponent in a parent container, you might be able to watch that:

watch: {
  activeComponent() {
    this.refreshData(); // or whatever you need to do

A third option might be to add an event listener on whatever parent element is triggering this component to be "viewed" - a button click or otherwise.

Good luck!

06 Jul
2 years ago

jplhomer left a reply on Laravel Envoy Not Working

@robertmylne ha, good to know!

05 Jul
2 years ago

jplhomer left a reply on Laravel Envoy Not Working

Hmm I'm noticing that in the docs it looks liked @servers expects a multidimensional array of user/IPs. Maybe try that?

The docs are inconsistent throughout though - so if this fixes your issue, we should open a PR to get them updated :thumbsup:

jplhomer left a reply on How To Stop Laravel (5.4) Thinking A 3rd Party API Call Is A Laravel Controller?

This is a namespace issue. Since your controllers live in the App\Controller namespace, PHP is trying to resolve the Sprout* classes to that same namespace.

The easiest way around this is by escaping your class names with a backslash:

\SproutVideo::$api_key = 'abcd1234';
$token = \SproutVideo\UploadToken::create_upload_token();

P.S. I'd definitely recommend installing your dependencies with Composer: it removes the hassle of having to include vendor/autoload.php every time :)

jplhomer left a reply on Progress Bar With Axios

It looks like axios expects a property/method named onUploadProgress instead of progress. Maybe you could try switching that out?

Debugging JS is always kind of tricky. I'd start by adding a console.log() statement outside of your if statement inside the method to see if progress is even executing. Good luck!

23 Sep
2 years ago

jplhomer left a reply on If Variable Exists Fire Event

Hi @jbowman99,

As @InaniELHoussain mentioned, an alternate solution would be to create a route for that referral:

Route::get('/referral/{token}', function($token) {
  // Do things with $token

But if you'd like the seamless experience of doing it asynchronously, you could send a GET AJAX request with that data:

if ('ref') != -1 ) {
  // Get query params:
  var token = '???';
  fetch('/your/referral/endpoint/' + token).then(function(result) {
     console.log('referral recorded!');
     console.log('something bad happened');