msslgomez

msslgomez

Member Since 10 Months Ago

Experience Points
17,010
Total
Experience

2,990 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
7
Lessons
Completed
Best Reply Awards
5
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 4
17,010 XP
Sep
25
23 hours ago
Activity icon

Replied to Rerun A Controller Method When Fails

@automica Right I understand, and in this case I don't need the resetToken method since this way it's unneeded.

Activity icon

Replied to Rerun A Controller Method When Fails

@automica So you think I should put what's inside resetToken where $this->resetToken(); is instead? Removing the method altogether? Like this?

try {
    $response = $client->request('POST', $api_url, [
                    'json' => $params,
                    'headers' => $headers
    ]);
    return $response->getBody();

}catch (ClientException $e) {
    if ($e->getCode() === 401) {
        Cache::forget('payment_token');
        Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });
        sleep(2);
    }
}
Activity icon

Replied to How To Make A Proper Loop - Vue

@ivanradojevic Sorry about changing that but the array you provided is called data and I was testing it on one of my projects so I had to change that detail. Glad it worked.

Activity icon

Replied to Rerun A Controller Method When Fails

@automica

This is what I'm trying to do

  • get a valid token from api
public function getToken()
    {
        Cache::forget('payment_token');
        $key = Cache::rememberForever('payment_token', function () {
            $client = new Client();

            $params = [
                'client_id' => env('CLIENT_ID'),
                'client_secret' => env('CLIENT_SECRET'),
                'grant_type' => 'client_credentials',
            ];

            $headers = [
                'Accept' => 'application/json',
            ];

            $response = $client->request('POST', 'https://api.pay/token/', [
                'json' => $params,
                'headers' => $headers
            ]);

            $res_body = json_decode($response->getBody()->getContents());

            return $res_body->access_token;
        });

        return $key;
    }
  • use this token in the other requests, ill put the full code for the simpleCharge method
public function simpleCharge()
    {
        for ($retry = 3; $retry > 0; $retry--)
        {
            $key = Cache::rememberForever('payment_token', function () {
                return $this->getToken();
            });

            $client = new Client();
            $url = env('BASE_URL');
            $api_url = $url . '/charges/simple/create/';
            $params = [
                'amount' => 90.32,
                'description' => 'Plan 1 service charge',
                'entity_description' => 'Plan 1',
                'currency' => 'usd',
                'credit_card_number' => 4242424242424242,
                'credit_card_security_code_number' => 123,
                'exp_month' => 11,
                'exp_year' => 2020
            ];

            $headers = [
                'Authorization' => 'Bearer ' . $key,
                'Accept' => 'application/json',
            ];

            try {
                $response = $client->request('POST', $api_url, [
                    'json' => $params,
                    'headers' => $headers
                ]);

                return $response->getBody();

            }catch (ClientException $e) {
                if ($e->getCode() === 401) {
                    $this->resetToken();
                    sleep(2);
                }
            }
        }
    }
  • If the $response fails then it goes into the catch and I could get a couple status codes to show what went wrong
401	Unauthorized
403	Forbidden 
404	Not Found 
405	Method Not Allowed 
429	Too Many Requests 
500	Internal Server Error 
503	Service Unavailable 

In my case I only need to reset the token if I get a 401, I'll try to handle the other code later. If I do get a 401 then I need to get a new token

 public function resetToken() {
        Cache::forget('payment_token');
        Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });
        return;
    }

I'm 100% sure this could be refactored to be made better, what I understood this code to do with this

 Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });

Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. For example, you may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the database and add them to the cache.

If the item does not exist in the cache, the rememberForever passed to the remember method will be executed and its result will be placed in the cache.

So I need to forget the payment_token I have and replace it with a new one, If I don't forget it since it is rememberForever I'll be getting the same old expired token over and over.

Activity icon

Replied to Rerun A Controller Method When Fails

@laracoft Do I need the break still if I have a return like this?

try {
    $response = $client->request('POST', $api_url, [
        'json' => $params,
        'headers' => $headers
    ]);

    return $response->getBody();

}catch (ClientException $e) {
    //
}
Activity icon

Replied to Rerun A Controller Method When Fails

@laracoft I fixed it by refreshing and clearing browser cache after I changed the dd to a return, now I can see the data. I have a question would there be any reason why your code would somehow run twice and charge a card twice since it is in a for loop?

Activity icon

Replied to Rerun A Controller Method When Fails

@laracoft Right now in the browser.

Activity icon

Replied to Rerun A Controller Method When Fails

Sorry the best answer was a mistake, I'll change it when the problem is solved

Activity icon

Replied to Rerun A Controller Method When Fails

@automica I don't want to return $this->simpleCharge(); because the resetToken method could be called from many other methods as well, that's why I thought if I added the method as a parameter I could rerun the correct one.

Activity icon

Replied to Rerun A Controller Method When Fails

@laracoft After trying it I get a 200 status response but can't see any of the info. I tried changing dd($response->getStatusCode()); to return $response->getBody(); but no change I do need to see the info being returned

Activity icon

Awarded Best Reply on How To Make A Proper Loop - Vue

@ivanradojevic Try this out, you should look more carefully at the documentation for Element-ui, like this example, you're missing the indexes which are what make the menu work.

<el-menu>
    <el-menu-item index="1">Processing Center</el-menu-item>
    <el-submenu index="2">
        <template slot="title">Workspace</template>
        <el-menu-item index="2-1">item one</el-menu-item>
        <el-menu-item index="2-2">item two</el-menu-item>
        <el-menu-item index="2-3">item three</el-menu-item>
    </el-submenu>  
</el-menu>

Taking the example above into account you need to add the indexes to your menu items, if you look carefully the menu items index starts on 1 not 0 so we need to add one to the index we get from the v-for since that one does start on 0. Another thing is the submenu's menu-item index as you can see it's a little different as it takes two different indexes and parent submenu and it's own index.

 <div v-for="(category, index) in data" :key="index">
    <el-menu-item :index="index + 1" v-if="!category.childrens.length">
        {{ category.slug}}
    </el-menu-item>

    <el-submenu :index="index + 1" v-if="category.childrens.length">
        <template slot="title">{{ category.slug }}</template>
        <el-menu-item v-for="(subcat, inx) in category.childrens" :index="(index + 1) + '-' + (inx + 1)">
            {{ subcat.slug}}
        </el-menu-item>
    </el-submenu>
</div>

Hope this helps.

Also there is a Vue category, this question belongs in that category not the Laravel category since this doesn't really have anything to do with Laravel itself.

Activity icon

Started a new Conversation Rerun A Controller Method When Fails

I'm trying to use a payment api to create a charge on a credit cart, this request needs a token but this token expires so if the token is expired I need to call the method that gets a new token and then rerun the original method for the charge on the card.

This is what I have

public function simpleCharge()
    {
        $key = Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });

        $client = new Client();     

        try {
            $response = $client->request('POST', $api_url, [
                'json' => $params,
                'headers' => $headers
            ]);
            dd($response->getStatusCode());
        }catch (ClientException $e) {
            if ($e->getCode() === 401) {
                $this->resetToken($this->simpleCharge());
            } else {
                return 'else';
            }
        }
    }

    public function resetToken($method) {
        Cache::forget('payment_token');
        Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });

        $this->$method;
    }

However this is returning

Maximum execution time of 120 seconds exceeded

I'm not sure if it's because of a loop that's being created or why, when doing these on their own they take a 2-3 seconds at the longest.

What is the correct way to do this?

Activity icon

Replied to How To Make A Proper Loop - Vue

@ivanradojevic Try this out, you should look more carefully at the documentation for Element-ui, like this example, you're missing the indexes which are what make the menu work.

<el-menu>
    <el-menu-item index="1">Processing Center</el-menu-item>
    <el-submenu index="2">
        <template slot="title">Workspace</template>
        <el-menu-item index="2-1">item one</el-menu-item>
        <el-menu-item index="2-2">item two</el-menu-item>
        <el-menu-item index="2-3">item three</el-menu-item>
    </el-submenu>  
</el-menu>

Taking the example above into account you need to add the indexes to your menu items, if you look carefully the menu items index starts on 1 not 0 so we need to add one to the index we get from the v-for since that one does start on 0. Another thing is the submenu's menu-item index as you can see it's a little different as it takes two different indexes and parent submenu and it's own index.

 <div v-for="(category, index) in data" :key="index">
    <el-menu-item :index="index + 1" v-if="!category.childrens.length">
        {{ category.slug}}
    </el-menu-item>

    <el-submenu :index="index + 1" v-if="category.childrens.length">
        <template slot="title">{{ category.slug }}</template>
        <el-menu-item v-for="(subcat, inx) in category.childrens" :index="(index + 1) + '-' + (inx + 1)">
            {{ subcat.slug}}
        </el-menu-item>
    </el-submenu>
</div>

Hope this helps.

Also there is a Vue category, this question belongs in that category not the Laravel category since this doesn't really have anything to do with Laravel itself.

Activity icon

Replied to Store Value Globally In Controller

@snapey I'm going to try and figure out what the 36000 actually is time wise, the token I got yesterday right now is returning a 401 so it's expired, so I know probably it's closer to 10 hours than 36 seconds.

So basically I should check the status code if it's a 401 get the token again, and if its a 200 proceed. Should I handle all the status codes separately in like a switch? According to their docs there are 10 status codes that could be returned.

Sep
24
1 day ago
Activity icon

Replied to Store Value Globally In Controller

@snapey Oh I understand, so the method itself would go in that return.

public function getToken()
    {
        $key = Cache::rememberForever('payment_token', function () {
            $client = new Client();

            $params = [
                'client_id' => env('4GEEKS_CLIENT_ID'),
                'client_secret' => env('4GEEKS_CLIENT_SECRET'),
                'grant_type' => 'client_credentials',
            ];

            $headers = [
                'Accept' => 'application/json',
            ];

            $response = $client->request('POST', 'https://api.pay/token/', [
                'json' => $params,
                'headers' => $headers
            ]);

            $res_body = json_decode($response->getBody()->getContents());

            return $res_body->access_token;
        });
        
        return $key;
    }
Activity icon

Replied to Store Value Globally In Controller

@snapey Like this?

public function getToken()
    {
       //get $res_body

        $key = Cache::rememberForever('payment_token', function () {
            return $res_body->access_token;
        });

        return $key;
    }

public function simpleCharge()
    {
        $key = Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });

       //use $key 
    }
Activity icon

Replied to Store Value Globally In Controller

@automica the 36000 expiry time comes from the API call for the token. I don't know if it's in seconds or ms or what. But yea I think maybe if its 36 seconds then I would need to get a new token every time a want to make a API request. But I'm not sure

Activity icon

Replied to Store Value Globally In Controller

@snapey Like this

public function getToken()
    {
       //get $res_body

        return $res_body->access_token;
    }

public function simpleCharge()
    {
        $key = Cache::rememberForever('payment_token', function () {
            return $this->getToken();
        });

       //use $key 
    }
Activity icon

Replied to Store Value Globally In Controller

@snapey Where would I put that?

Does the 36000 expire time refer to ms, that would mean each token is only good for 36 seconds? If it is than I gravely misunderstood that part.

Activity icon

Replied to Store Value Globally In Controller

@snapey You're right it does say the token expires, this is what gets returned when I get a token

{"access_token": "70LNuFOWoZ", "token_type": "Bearer", "expires_in": 36000, "scope": "read write groups"}

Probably easiest is to store in cache with remember forever. Wrap your function that returns the api code in a cache callback

I'm not following you here. What should I do?

Activity icon

Replied to Store Value Globally In Controller

@snapey I'm trying to use an API for processing credit cart payments and the first step is getting the authorization token, after that every HTTP request must include that token in it to work. The docs for this api a vague all it says is After getting the token it must be sent in every request going forward, I'm assuming that means I only need to get it once. So I need to save it somewhere it won't get removed or lost.

Activity icon

Replied to Store Value Globally In Controller

@snapey I don't have that but I did do dd(session()->all()) and it returns an empty array. As far as I understand I only need to get the token once and use it, do session variable go away when someone logs out or after redirects? Maybe it would be better to store it in the .env?

Activity icon

Replied to Store Value Globally In Controller

@drewdan It's still null, I removed the dd after setting the session value but I'm not sure if I need to add a return or something.

Activity icon

Replied to Store Value Globally In Controller

@snapey if I need this value to always be there would session be the correct place to save it? I'll remove that dd.

Activity icon

Replied to Store Value Globally In Controller

@drewdan SESSION_DRIVER=file

Activity icon

Replied to Store Value Globally In Controller

@drewdan I'm not sure what you mean by session driver I just wrote session() and used the first one. According to the docs that the global helper.

The value I need to save is a string.

Activity icon

Started a new Conversation Store Value Globally In Controller

I need to save a token to then use in all methods of a specific controller, I tried putting it in session but then when I try to use it it says it's null.

This is what I have where I get the token, which does return a token value

session(['access_token' => $res_body->access_token]);

dd(session('access_token'));

But when I try to use session('access_token') in another method it returns null.

What is the best way to achieve this?

Activity icon

Awarded Best Reply on Products Related To Categories, But How

I actually have a project with exactly this set up. Personally I don't like the pivot table name in alphabetical order since sometimes the name doesn't make that much sense.

This is what I have

Schema::create('product_categories', function (Blueprint $table) {
    $table->integer('product_id')->unsigned();
    $table->integer('category_id')->unsigned();
    $table->foreign('product_id')->references('id')->on('products');
    $table->foreign('category_id')->references('id')->on('categories');
});

Models, since the name is not the conventional one I pass the name of the table to the return

//Category
 public function products()
    {
        return $this->belongsToMany(Product::class, 'product_categories');
    }

//Product
public function categories()
    {
        return $this->belongsToMany(Category::class, 'product_categories');
    }

and as @automica said just call like $product->categories() or vice-versa.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan I was really confused I don't use the shell so I didn't know that, but good to know for the future.

Activity icon

Replied to Products Related To Categories, But How

@automica yea I know but sometimes the name doesn't sit well with me haha, I still have a lot to learn but maybe in my next project I'll do it how Laravel intends me following the docs closely.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

😱😱😱😱😱 THANK YOU!! I'm been struggling for days with this.

Activity icon

Replied to Products Related To Categories, But How

I actually have a project with exactly this set up. Personally I don't like the pivot table name in alphabetical order since sometimes the name doesn't make that much sense.

This is what I have

Schema::create('product_categories', function (Blueprint $table) {
    $table->integer('product_id')->unsigned();
    $table->integer('category_id')->unsigned();
    $table->foreign('product_id')->references('id')->on('products');
    $table->foreign('category_id')->references('id')->on('categories');
});

Models, since the name is not the conventional one I pass the name of the table to the return

//Category
 public function products()
    {
        return $this->belongsToMany(Product::class, 'product_categories');
    }

//Product
public function categories()
    {
        return $this->belongsToMany(Category::class, 'product_categories');
    }

and as @automica said just call like $product->categories() or vice-versa.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan I'm still getting the same result, the docs say it's oAuth2 but since I'm trying to do a HTTP request I don't know if I have to do it differently or not.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan Now I get the same error I get in Insomnia but that's a good thing since it's not the previous errors.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan yes that's correct this is only meant to get a token, I tried it on Insomnia and sent the grant_type, client_id and client_secret as headers but get this

"error": "unsupported_grant_type"

Not sure why since I copied the grant type from the docs but I'm not getting the 405 method not allowed error

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@saurav77 That's not really answering my question how is that supposed to get it to send as a post? It's still a get.

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan if I change the route and not the request method in the controller method I still get the same error and the documentation says it should be a post request. If I change it all to get I get this error

GuzzleHttp\Exception\ClientException Client error: GET https://api.payments.4geeks.io/authentication/token resulted in a 405 Method Not Allowed response

Activity icon

Replied to GET Method Is Not Supported For This Route. Supported Methods: POST.

@drewdan in my browser I was trying to use Insomnia but I just decided to use the browser instead.

Activity icon

Started a new Conversation GET Method Is Not Supported For This Route. Supported Methods: POST.

I'm using a post request, this is the code

//API routes
Route::post('getToken', '[email protected]');

//getToken Method
        $client = new Client();
        $params = [
//            'client_id' => env('4GEEKS_CLIENT_ID'),
//            'client_secret' => env('4GEEKS_CLIENT_SECRET'),
        ];

        $headers = [
            'grant_type' => 'client_credentials',
            'client_id' => env('4GEEKS_CLIENT_ID'),
            'client_secret' => env('4GEEKS_CLIENT_SECRET'),
        ]; 

        $response = $client->request('POST', 'https://api.payments.4geeks.io/authentication/token', [
            'json' => $params,
            'headers' => $headers
        ]);

        return $response->getBody();

I'm using Guzzle to try and use this 4Geeks payment api (http://docs.payments.4geeks.io/?javascript#authentication) that's the link in case you want to check it out, it's in Spanish. It's really vague I'll give a brief translation on the authentication part

4Geeks Payments uses oAuth2 so be sure to send grant_type=client_credentials. Also you must send client_id=<4geeks-payments-client-id>, client_secret=<4geeks-payments-client-secret>. This will return an access_token, which will need to be sent in every other request going forware. Remember to never have these credentials visible to anyone, never upload them to repositories like GitHub and never share them. It's recommended to use these credential in environment variables.

I'm not sure where to send the grant_type, client_id, and client_secret, in the headers or params.

I did try running composer dumpautoload and php artisan route:cache but I'm still getting that error. What can I do to fix it?

Sep
23
2 days ago
Activity icon

Replied to How To Use Node.js API

@sinnbeck Regardless of language, what are the base steps to implement something like this? According to the javascript site first you need to send your credentials via oAuth2 and get a token to then send along with the rest of the requests. That's the first hurdle since the requests use js, how would I go about doing that? I pretty desperate at this point, I don't have many options to start with.

Activity icon

Replied to How To Use Node.js API

@sinnbeck Realitically I need only the authentication, accounts, changes parts. This is for simple online store so payment plans or subscriptions aren't needed. I'll translate anything you need, here I translated the Create a Charge part so you can see.

Create a Charge
await gpApi.charges.create({
  amount: 90.32,
  customer_key: 'GfGsOKTZVlTKyn7khcihXYuEUx0nBxb',
  description: 'Plan 1 service charge',
  entity_description: 'Plan 1',
  currency: 'usd',
})
Returns a HTTP 201 Created status

This endpoint creates a charge, in other words, creates a charge and takes it out of the client''s card, using their financial data.

HTTP Request
POST https://api.payments.4geeks.io/v1/charges/create/

Fields
Parameter	Description	Type	Required
customer_key	Customer key, for getting the card info of the associated client.	string	true

amount	Amount of money for the charge.	float	true

description	Description with which you can search for the transaction.	string	true

entity_description	Description for the account status of the client''s card. Max 22 caracteres.	string	false

currency	Currency of the transaction (crc, usd), by default the customer currency is going to be used. string	false
Activity icon

Replied to How To Use Node.js API

@snapey Did you see the other link I provided? I was told maybe I could use the API directly without the library above. Would that be possible?

Activity icon

Started a new Conversation Using Paddle For Credit Card Payments Not In USA?

I'm trying to make an online store BUT since I live in Costa Rica I'm having trouble with the actual payment service or API. In my country there is this 4Geeks API http://docs.payments.4geeks.io/?javascript#introduccion and also another service called GreenPay but I've been more looking into the 4Geeks one however I don't know how to implement it in my project.

Also I was looking at the cashier options laravel has already and found that Paddle supports Costa Rica, well not "support" just doesn't explicitly say it's not allowed. https://paddle.com/support/countries-supported/ Would using Paddle be a viable option to consider?

Also if anyone can guide me on using a REST API like 4Geeks that would be super helpful, I really have never used something like this and don't know how to start.

Activity icon

Replied to How To Use Node.js API

@sinnbeck @snapey @michaloravec Any ideas? I also have this page, it is in Spanish but there is a lot of example code here http://docs.payments.4geeks.io/?javascript#introduccion. If you could take a look that would be super helpful.

Sep
22
3 days ago
Activity icon

Started a new Conversation How To Use Node.js API

I'm trying to implement a node.js API in my project but I'm at a complete loss of what to do or where to start. This library is for credit card payments https://github.com/cayasso/gpayments I haven't used a library like this before so I'm confused how to get it to work and there aren't many instructions on the github page.

What should I do to get it working?

Activity icon

Started a new Conversation Use A Node.js Library With Laravel + Vue

This is a library for processing payments in my country (CR) for node.js but I don't even know where to start since this isn't necessarily for Laravel I'm lost on how to implement it and use it.

https://github.com/cayasso/gpayments

Anyone who can guide me on where the code in the examples goes, I'm also using vue in case that is important. Any tips and help is greatly appreciated.

Sep
18
1 week ago
Activity icon

Replied to Get Model Items Included In Relationship (categories That Have Products)

@michaloravec I need to send it to a vue file so without me adding that I don't get a name attribute for each category

Activity icon

Replied to Get Model Items Included In Relationship (categories That Have Products)

@michaloravec Is model function used like this?

$categories->each(function ($item) {
    $item->name = $item->getNameAttribute();
});