DARK MODE 

Posted on Tuesday, December 28, 2021 by

Create Instagram Clone with Laravel (Part 6): Create a New Controller for Profile to Fetch Data From Database

In this post, I covered from minute 58:35 until 1:10:05 of this video.


We're going to create a controller because like it has been mentioned before, if we want to do anything with data, we do it in the controller, not in the view. Right now, we need to pulled data from our databasae so we can display our username in our profile.

Right now, to view our profile, we first need to log in. But that's not how Instagram works, right? We should be able to visit a user's profile whether we're logged in or not. In order to achieve that, we need to create a new controller for the Profile. Like already mention in previous post, controllers is where all of logics is stored.

Creating a new controller
First, let's understand more how controller works and how do we call the method or function in it. Take a look at routes > web.php.


From the photo above, we now know how to call a controller. Let's take a look at HomeController.php in app > Http > Controllers. This controller is automatically generated when we run the command php artisan ui:auth in part 3 before.




The codes on line 9 - 17 is the authentication process that what makes our profile can't be viewed when we're not logged in. On line 19 - 27 is a function that has the name of index. Inside this function, we can see that it is returning a view called home. This home represents the home.blade.php located in resources > views. There's no need to write .blade.php because Laravel is smart enough to know we're actually referring to that file. 

Now that we know the basic of controller and how to call it, let's try to make a new controller to display our profile. We already know that php artisan command will display all the command list we can use. Now, if we run php artisan help <command name>, you can see what sort of options that command has and what sort of required parameters you have to pass in it. Because we're gonna make a controller, run php artisan help make:controller.


In the usage, you can see that after make:controller, we need to pass in any number of options from Options list. And then we have name as argument. Anything in the <  > means this parameter is required. I want to make a profile controller and name it ProfilesController so I run php artisan make:controller ProfilesController. Now we have a new controller!
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

namespace App\Http\Controllers;

 Illuminate\Http\Request;

class ProfilesController extends Controller
{
    //
}
app > Http > Controllers > ProfilesController.php

Direct Laravel to new controller
Let's go ahead and copy line 24 - 27 codes from HomeController.php to our new controller. This is because we want this controller to return the view of home.blade.php which displays our profile.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProfilesController extends Controller
{
    public function index()
    {
        return view('home');
    }
}
app > Http > Controllers > ProfilesController.php

We're not done yet. Now we just need to direct Laravel so it will use this new controller instead of the home controller. Let's go back to web.php and just change the HomeController to ProfilesController.

22
Route::get('/home', [App\Http\Controllers\ProfilesController::class, 'index'])->name('home');
routes > web.php

Done! We're now is using the new controller. You should be able to visit '/home' even without logging in.

Fetching and displaying username from database to profile
Now, we need to change the /home URL path to something else. In Instagram, user's profile URL would be something like /username. Before we're going to do that, we first need to know about restful resource controllers. If you've never know about this concept before like me, it is basically a predetermined number of verbs that you can use. Each of these actions will be matched to a particular URL, verb and route name. This is a very important concept because it will make your code base much cleaner, your controllers lighter and your app much easier to update.

Verb Path Action Route Name
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy

So that we're clear on what the actual procedure should be, we first will try to change the URL to something like /profile/userid. In order to do that, we need to apply the 4th action in the table which is the show action because we are getting a specific profile for only one user, not all of them. That's also why we're not using the index action. The curly bracket notation means it's a variable and it's going to change, which is perfect because user's id is unique. Let's make the changes in web route.
22
Route::get('/profile/{user}', [App\Http\Controllers\ProfilesController::class, 'index'])->name('profile.show');
routes > web.php


So how do we get the access to data for {user}? Let's go back to ProfilesController.php. In the index function, we need to define a variable to get the user id, so I named it $id. To get the id, we need to fetch the data from our database. But first, let's check if the function is able to get and display the $id value correctly by using the dd() helper function. dd() or die and dump is used to dump a variable's contents to the browser and stop any further script execution. So whatever you write to replace the variable in {user} will be displayed on the page. It will also stop executing other codes so we'll not be seeing it returning the home view. Let's try.

10
11
12
13
14
    public function index($id)
    {
        dd($id);
        return view('home');
    }
app > Http > Controllers > ProfilesController.php

You'll get like this. Any value you enter after /profile/ will be displayed. This means the index function able to get and display the id we dump as temporary replacement for the variable {user}. Now, we just need to get the real id from database.




Remember the User.php in app > Models that represents a single user inside our database? We need to call that file and ask Laravel to find the user id from it. Let's try die and dump on that.

5
6

12
use App\Models\User;
use Illuminate\Http\Request;
..
dd(App\Models\User::find($id));
resources > views > home.blade.php
Result:


Great! Now we know that we're able to fetch the data of the user. Let's remove die and dump and initialize the data to a variable. I named this variable $user because it's not only containing user id, but other data as well. Then, we need to pass the data to the view. To do that, in the second argument of the return view [ ], we can pass in an array. If you already know some basic of programming, you know that it's common to display data from database using an array. We need to initialize the value from $user to another variable. This new variable inside ' ' is what we're going to use whenever we want to call the data inside our view.

12
13
14
15
        $user = User::find($id);
        return view('home', [
            'user' => $user
        ]);
app > Http > Controllers > ProfilesController.php

To display the data wherever inside our view, the concept is similar to echo in php, where we write <? echo $variablename >. In Laravel, we do it inside a curly bracket, like {{ $variableName -> dbColumnName }}.

10
11
12
            <div>
                <h2 class="font-weight-light">{{$user -> username}}</h2>
            </div>
resources > views > home.blade.php

Great! Now, try to open the profile for a user and you should be getting the username. This username isn't hardcoded like before but it's a data that has been pulled from the database!

Notes: I changed the profile photo.


No comments:

Post a Comment