Display Activity Feed In The Browser

Display Activity Feed In The Browser

Now that we have the logic in place to record user activity in the database, in this tutorial we will work on fetching that user activity from the database and rendering it to the browser. To begin, we’ll just verify that new activities are in fact being recorded by manually checking in the database. Once that is complete, we can alter our controller logic to fetch user activity from the database. Next up, we’ll begin crafting the view files to display this information in the form of an activity feed. Finally, we’ll work a bit on grouping of different activities, and also refactoring to components in the view.

Testing User Activity Feature From The Browser

All of the supporting tests seem to indicate that the recording of user activity for the activity feed is working just great. We haven’t actually tried entering some new threads and replies via the browser to see if those activities are recorded. If they are recorded, then we should see those activity records in the activities table of the database. Let’s try that now.

First off, on the live server – we’ll need to manually run the migrations. Why? Because remember, our tests are doing everything in memory via an SQLite database. When the tests run, migrations are run, a whole new database schema is set up, then everything is rolled back upon completion. Anyhow, let’s run the migration.

vagrant@homestead:~/Code/forumio$ php artisan migrate
Migrating: 2018_01_30_164752_create_activities_table
Migrated:  2018_01_30_164752_create_activities_table

Great – the activities table is now in place. We can add a thread and see if it is recorded in the database.
testing user activity feed

Checking in the database shows that the new Thread Activity was created. Cool!
new thread activity recorded to the database

Let’s try one more thing. We need to make sure reply activity works as well.
testing user reply activity

Ah ha! It looks like we now have two activities in the database! It seems to be working.
new reply activity recorded in the database

Fetching Activity Data For The User Profile

The goal here is that when we view a user profile page, we will now see all the activity associated with that user. The show() method of the ProfilesController is where this occurs, so let’s go ahead and start fleshing out the api for this. We want to make use of an activity() method like so:

This means we need to define the relationship on the User Model. This is a hasMany relationship that is pretty easy to set up.

Viewing the relationship raw data

Very quickly, we can just add return $user->activity; to the beginning of the show() method to see what gets sent to the browser. If we visit the user profile of http://forum.io/profiles/NikolaTesla we see that his activity is in fact being displayed. So far he has one Thread activity and two Reply activities.
acttivity relationship working

Eager Loading The Subject Activity

It’s a good idea to make use of eager loading when you can, so we can add that to the method chain like so: return $user->activity()->with('subject')->get(); Now we can see that each Activity also includes with it the Subject of that activity. Very neat!
eager loading working nicely

With these steps so far, here is where the show() method stands in the ProfilesController.

Preparing The profiles/show.blade.php View File

Getting the activity data from the database is now complete. The code above shows us fetching that activity data, and then sharing the data to the view file. We’ll need to update that show.blade.php view file to process the data now.

Basic View Side Polymorphism

The nature of activities is that there can be multiple types. There may be a Thread activity, or a Reply activity, or perhaps a Favorite activity. In a case like this you could set up multiple if else branches in the view to determine which to show, or you could set up some partial view files and use polymorphism to set this up. First we can set up some partial view files like so.

creating partial view file

nested partial view file

Now, in the main profiles/show.blade.php view, we can include different partial files like so:

The variable of $activity->type is going to be different depending on if a thread or a reply is being passed through. This way, the correct partial panel gets loaded with no need for extensive if else blocks. Pretty neat!

Adding markup to the partial views

We did a good job making show.blade.php a neat and tidy file, now we need to add some markup in the actual partial files to display each activity type. Here is a start for the two partial view files.



Making sure the most recent activities are at the top of the profile page.

We also want to put the most current or latest activities at the top of the profile page when a user visits. That is pretty easy to do by making sure we include the latest() method in the controller.

Now, the beginnings of our activity feed is starting to take shape!
basic activity feed

Linking To Individual Activities

On the activity feed, we should be able to click a link to take us to the specific activity that is being displayed. We can do this for both replies and threads.

On the Reply model, we are going to need a new belongsTo relationship. A Reply belongs to a Thread, represented by this code in the Reply model.

Now we can update both partial files once again to include links to each individual activity.



Ok! The activity feed is looking pretty good and now also has links going back to each thread or reply.
activity feed with links

Grouping Activity By Day

Now we want to set up the activity feed so that all activities for any given day are grouped together. For this we will need to update the show() method in the ProfilesController to make use of a groupBy() clause on the collection. That looks like so:

In addition, we need to now update the show.blade.php view as follows.

Now the activity feed is looking pretty good! Each day has a grouping of activities which is really slick.
activity feed grouped by day

Refactoring To A Component

We got the feed to work, and we’re pretty happy with that. Now however, we need to do some refactoring to make sure our view files are not a mess. To complete this, first we will create an activity component like so.
view component

The markup will appear like so in the component:

The other two partial view files now make use of the @component directive like so. Also note the use of the slot feature similar to how Vue uses slots.



The page loads the same, but now we have a much better system to put together our views. I know, I know, you’re thinking… But Why?

Well, think about if you end up having say another three or four activity types. You will now need three or four more partial view files for each type. Now let’s say you want to alter the markup slightly or change the styling on the activity feed. Guess what. Yep that’s right, without the activity.blade.php component, you would need to update five or six different view files. Yuck! Instead, with the single activity.blade.php file, you can make changes to markup or styling there once without the need to open up and edit all of those other partial files. Cool. Super cool in fact!

Display Activity Feed In The Browser Summary

Great job in setting up this activity feed for the application. It was a bit involved, but nothing we couldn’t handle. Additionally, we also learned about the groupBy() on collections and using components in the view files. Very nice!