andersb

andersb

Member Since 2 Years Ago

Experience Points
9,680
Total
Experience

320 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
83
Lessons
Completed
Best Reply Awards
1
Best Reply
Awards
  • start your 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-in-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 Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist 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.

Level 2
9,680 XP
Jul
08
5 days ago
Activity icon

Started a new Conversation Require Packages Like AlpineJS And MapBox GL JS As Dependency Or CDN?

We are using quite a lot of 3rd party packages like AlpineJS and MapBox GL JS and are facing an issue how to properly import these so they are available from scripts in blade files.

Let us say that we need to show a MapBox on a page using blades. We could do this like so:

// /resources/views/map.blade.php
@extends('layouts.app')

@section('content')
    <div id='map' style='width: 400px; height: 300px;'></div>
    <script>
        mapboxgl.accessToken = '<your access token here>';
        var map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v11',
            center: [-74.5, 40],
            zoom: 9
        });
    </script>
@endsection

Now the code above needs access to mapboxgl and this is the reson for this post. How do we make that available? As I see it we have the following options:

NPM dependency

Install MapBox as a npm dependency and make it available in resources/js/app.js like so:

//resources/js/app.js

window.mapboxgl = require('mapbox-gl');

where we make sure to include public/app.js in the header of the page (not the bottom since the script will run before the library is made available causing an error Uncaught ReferenceError: mapboxgl is not defined):

<!-- /resources/layouts/app -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        ...
        <script src="{{ mix('js/app.js') }}"></script><!-- Important this is in the head section -->
    </head>
    <body>
        @yield('content')
    </body>
</html>

but won't that affect all page loads forcing the browser to load a potential large app.js file before processing the HTML?

CDN in head-section

Use a CDN in the <head> of our /resources/layouts/app file like so:

<!-- /resources/layouts/app -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        ...
        <script src='https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.js'></script>
    </head>
    <body>
        @yield('content')
    </body>
</html>

This script will still have to load on each pageview but loads through a potentially fast CDN and can be cached by the browser across sites. But now we do not get any information from NPM when an update is available and our site needs to fetch a lot of javascript files this way.

Conditional CDN

Use a CDN like above but only conditionally add it to the <head> section using the @push('scripts') syntax (require a @stack('scripts') part in the <head> section like described in the Laravel Docs)

<!-- /resources/layouts/app -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

    <head>
        <meta charset="utf-8">
        ...
        @stack('scripts') <!-- This will output any scripts pushed to the 'scripts' stach -->
    </head>
    <body>
        @yield('content')
    </body>
</html>

Where we push the CDN on the pages where the map is needed:

// /resources/views/map.blade.php
@extends('layouts.app')

@push('scripts')
    <script src='https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.js'></script>
@endpush

@section('content')
    <div id='map' style='width: 400px; height: 300px;'></div>
    <script>
        mapboxgl.accessToken = '<your access token here>';
        var map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v11',
            center: [-74.5, 40],
            zoom: 9
        });
    </script>
@endsection

NPM dependency and wait for DOMContentLoaded

Install MapBox as a npm deendency (see above) but implemented the /public/app.js script in the bottom of the page and wait for the event DOMContentLoaded before initializing the mapbox:

// /resources/views/map.blade.php
@extends('layouts.app')

@section('content')
    <div id='map' style='width: 400px; height: 300px;'></div>
    <script>
        var map;

        document.addEventListener("DOMContentLoaded", function(event) {

            mapboxgl.accessToken = '<your access token here>';
            var map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/streets-v11',
                center: [-74.5, 40],
                zoom: 9
            });
        });
    </script>
@endsection

Conclusion

Maybe I am missing something, but it does not seem to me like there is an optimal solution that encapsulates all scenarios? :/

Jul
02
1 week ago
Activity icon

Replied to Optional Properties In Blade Component

Just a note for others checking this issue. When using anonymous components (components without an associated PHP Class) simply set the variables including any default values in the @props part of the blade file as described in the docs:

<!-- /resources/views/components/alert.blade.php -->

@props(['type' => 'info', 'message'])

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>
May
29
1 month ago
Activity icon

Awarded Best Reply on Github Actions + Dusk

@brainbox I just confirmed the issue, and maybe this would be a good opportunity to add this to the Laravel documentation, but the problem is simply that Github uses 127.0.0.1:8000 as host, so it is important that your .env file has set APP_URL=http://127.0.0.1:8000.

You can force this by setting the variable in your workflow like so:

...
- name: Run Dusk Tests
  run: php artisan dusk
  env:
    APP_URL="http://127.0.0.1:8000"

Does this solve your issue?

May
22
1 month ago
Activity icon

Replied to Github Actions + Dusk

Nice to hear that it worked for you @brainbox , and yes now the documentation includes this. Happy to help. Please mark this as solved.

May
20
1 month ago
Activity icon

Replied to Github Actions + Dusk

@brainbox I just confirmed the issue, and maybe this would be a good opportunity to add this to the Laravel documentation, but the problem is simply that Github uses 127.0.0.1:8000 as host, so it is important that your .env file has set APP_URL=http://127.0.0.1:8000.

You can force this by setting the variable in your workflow like so:

...
- name: Run Dusk Tests
  run: php artisan dusk
  env:
    APP_URL="http://127.0.0.1:8000"

Does this solve your issue?

May
12
2 months ago
Activity icon

Replied to Github Actions + Dusk

Can you start by posting the errors from Github Actions?

I suggest that you then have a look at your environment variables and perhaps dump these during debugging to ensure that you are using the correct ones during testing.

You are defining the DB_CONNECTION=sqlite and DB_DATABASE=:memory: in your phpunit.xml file: https://github.com/brokerbridge/github-actions/blob/master/phpunit.xml#L30 but you also create a MySQL database with a root user during setup. Note that you have not set a DB_PASSWORD in .env.example (which is copied to .env during setup) nor in .env.testing.

Note that you can pass certain variables directly to dusk using like done for phpunit here

May
11
2 months ago
Activity icon

Replied to Logging With Laravel HTTP Client

@bugsysha after having looked more deeply into the middleware then I agree with your proposal of using a dedicated class for this as it complicates things adding the middleware globally.

May
02
2 months ago
Activity icon

Started a new Conversation Logging With Laravel HTTP Client

Due to the simplicity of the Laravel HTTP Client then I am trying to implement this client for making external API request from our application.

However we have a requirement of logging requests and responses in certain situations but I have not found a nice way of doing this. There are a few available Guzzle logging middleware packages out there and it should be possible to always push this to the Guzzle stack using the AppServiceContainer as described here.

Now the problem is that I don't know how to pass any extra information to the middleware which could be used to determine whether or not the request/response should be logged but also this information would be nice to log as well.

Example:

Say we were to make an external API request to update the title of an external Post using the following API request:

$response = Http::patch('http://test.com/posts/'.$postId, [
    'title' => 'New title',
]);

Now it would be nice if I could pass a few parameters like $type='posts.update' and $postId=123 to the handler for example. This info could be use when logging the response (could be used for the filename or for a column in a DB record for the logged request/response for example).

Proposed solution

It looks like I can pass Guzzle Request Options like so (described in Laravel Docs here):

$postId = 123;
Http::fake();

$response = Http::withOptions([
    \GuzzleHttp\RequestOptions::DELAY => 444, // This shuld be an allowed option
  'x_type' => 'posts.update', // Custom option
  'x_id' => $postId, // Custom option
])->patch('http://test.com/posts/'.$postId, [
    'title' => 'New title',
]);

Http::assertSent(function ($request) {
  dd($request);
});

Problem

But as can be seen then none of the options are passed to the request - not even the allowed delay option. I am not sure what is wrong here :/ But I am not even sure if it is possible to use custom options, cause if that is not an option, then the only solution I can see is to use custom headers, but that could potentially lead to problems since these are actually sent to the client.

Does anyone know how to pass any data to the Guzzle middlewares?

Mar
23
3 months ago
Activity icon

Replied to Laravel Airlock, Api In The Same Domain (not Even Subdomain)

@luddinus bacially you have three relevant configurations here: APP_URL, AIRLOCK_STATEFUL_DOMAINS and SESSION_DOMAIN.

You can read details about this configuration in Mohammed Said's blog post here.

If you have everything on the same domain, then you should actually just put that domain in all three configurations. This is an example where we are running the application via Valet on http://example.test

APP_URL=http://example.test
AIRLOCK_STATEFUL_DOMAINS=example.test
SESSION_DOMAIN=example.test

While you cannot have your app and API on two completely different domains, then you can have them on different subdomains. This is from the blog post mentioned above:

That's why you can't have the API hosted in domain.com while the SPA is on another-domain.com. They both need to be on the same domain so they get the same session ID.

Say for example your app is on https://app.example.com and your SPA on https://example.com then you would use:

APP_URL=https://app.example.com
AIRLOCK_STATEFUL_DOMAINS=example.com,app.example.com
SESSION_DOMAIN=.example.com

Note the dot in the SESSION_DOMAIN which enables any subdomain.

For man people then you have both app and SPA in the same domain, but you are working both locally and on your production server. In this case, remember to set the appropriate values for all the three variables.