The best way to learn new things and features is build something on that feature. Of course you can learn the basics from video courses, but you have to use it to be confident.
That’s why I create a small “something” to learn and practice how to use and how Laravel Echo with Pusher works. It’s a kind of tutorial for me.
Therefore I build a simple website with comment module where users will get live notifications about comments.
For front end I will use vue.js because I’d like to learn the basics.
Another thing I would like to practice is testing in Laravel, especially the new browser test, Dusk.
Round one: brainstorming
The site will be very simple, at least at the beginning stage. It just has articles and on the article pages will be the comments.
Guest user can
- read articles
- read comments
Logged in users can
- read articles
- read comments
- write comments
- reply comments (v2)
- edit/delete own comments (v2)
- vote up/down comments (v2)
- Delete comments (v2)
- Set comments as spam (v2)
- New comment(s) on page
- Somebody replied your comment (v2)
- Somebody voted up/down your comment (v2)
Live log page for admin
- Comments live refresh (v2)
- Comment page for users to seeeditdelete own comments (v2)
- Comment page for admin to seeset spamdelete comments (v2)
Round two: database
Maybe it’s a little bit “old school” but I like design the database on paper in the beginning. I know, maybe (sure) it will change later, but when I design the database I design the whole system in my head. And I like seeing the database, table names, field names, not just in the migration files.
For the users I use the Laravel built in user migrations with a little modification because I need admin user.
I need two tables:
- Comments table
- Articles table
I know I’ll need models and controllers as well, so I create a model with migration and controller:
I need some dummy data. The simplest way is to use Laravel model factory and seeding.
That’s all, now I have dummy data in my database.
Round three: first tests and views
TDD - test driven development
I’m not a “maniac” TDD tester, so I’m using my browser for “visual” tests as well. I know you can create web application without open any browser, but that’s just not for me. I like to see my app during the development phase. But the tests are great of course, especially during refactoring.
Create a form
The next step is to create the actual form where the users can submit the comments for the article. Let’s try Laravel Dusk.
Because Laravel Dusk runs in a separate process, we can’t use the memory based sqlite database for testing. But we can create a separate
.env file for dusk where we can set another default database connection. Don’t forget to create the empty
Laravel Dusk fills in and submit the forms for us.
Sometimes I had problems with Dusk, but usually this helped:
Round four: Vue.js in action
The users can comment on an article’s page. In the show Article controller’s show method I call the
article.show view. In that blade file will use the vue components.
The comment-form component just a small input field, where a logged in user can publish the comment.
The comment-list component show the comments of the article. It loads the comments for the actual article with an ajax call:
It contains the comment component to show a simple comment.
In the header of the a comment I show the time, when the comment was created. First, I’d like to show it for ‘humans’ (eg: 2 days ago), secondly I’d like to refresh it, let’s say every minute.
If I don’t want to refresh it, I can do something like this in the Comment model:
After this it will be always loaded to the json file of the model. So when I get the comments in the
comment-list component (by the way, I use axios for Ajax calls), every comment’s has this attribute. In the html we will see something like this (good practise to include the original time as well, good for testing for example).
But, I’d like to refresh it every minute. In the comment-list component I have a
now data, and I refresh it every minute:
I give this data as
props to the child comment elements. In the comment component I have
A computed property in vue.js will re-evaluate when some of its dependencies have changed. I use
moment javacript package to convert the time to readable for humans.
When a user publish a comment, the
comment-form component post it to the Laravel, the backend. It saves it to the database and send back the comment, because we don’t want to reload the page to show the new comment. The
comment-form get this new comment, but somehow we have to notify the
comment-list about this new comment. I use a
vue component for this called
Event component is available for every vue components. This is how they can communicate with each other.
That’s all. The comments array gets this new comment, so it appears on the page.
Of course we have a validation for the form in the backend. If the
comment-form catches an error from the backend, it shows it to the user:
Round five: live notifications with Pusher
I use Pusher as broadcaster. They have free Sandbox Plan. More than enough to try this service.
I create an
event, CommentCreated.php and “fire” it when the comment is created:
comment-list.vue component listen to this event:
I flash a message about this new comment (how I flash, see later) and push it to a
newComment array. I could push it to the
comment array, but I don’t want to show it unless the user want to. I have two computed property in the
comment-list.vue and this is how I show the new message label in the header. If the user click on the label, I show the new comments
The Flash message
I learned this flash message technic from Jeffrey Way at a Laracasts course. It’s very simple, but it can be used both in back-end and front-end. Of course it can be upgraded to a more clever version, which has more options, but for now, it’s ok.
Basically the Flash component uses the
Event component. To use in the back-end, need to import this component in the basic layout and put a
flash message to the session. In every Js we just call
flash method to show a message. After 3 seconds it deletes the message.
Extra Dusk test
In this test we check, if the broadcast is working between browser pages.
This is just the tip of the iceberg but after we learn the basics we can easily develop something bigger. For me the next step is to build a complete comment module with
VueJS and integrate it to
Github page of the app.