AdonisJS: Templating, Authentication and Validators
In our previous post about AdonisJS we had covered introduction, installation, modeling, creating and displaying content, creating and deleting task. Let’s move on remaining part of it with this post.
A bit of templating
Our application is going to grow. In order to reuse some parts of the html, we are going to define a main layout, and include the specific code of each page into it.
Create a “layout_main.edge” file into “resources/views”. This file will include the base of our page, and will be used by each page we create.
<!DOCTYPE html> <html> <title>Task list</title> {{style('style')}} </head> <body> @!section('content') </body> </html>
Now you can refactor tasklist.edge
@layout('layout_main') @section('content') @if(flashMessage('taskHandling')) <span>{{ flashMessage('taskHandling') }}</span> @endif <form action="{{ route('TaskController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="title" placeholder="title" /> <input type="text" name="description" placeholder="description" /> <button type="submit">Create the task</button> </form> <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <form action="/task/delete/{{task.id}}" method="DELETE"> <button type="submit">Delete</button> </form> <p>{{task.description}}</p> </div> @endeach </section> @endsection
Authentication
You have probably already seen that there are some files to manage users in your project (“app/Models/User.js”)
First, let’s add a UserController :
#Choose "For HTTP requests" adonis make:controller UserController
Go to the router (“start/routes.js”) and some routes :
- two routes for the login and register process, displaying the templates with the forms
- two routes for receiving login and register data and handling user creation and login
- One route for the logout process
Route.on('/register').render('register') Route.on('/login').render('login') Route.post('/register', 'UserController.create') Route.post('/login', 'UserController.login') Route.get('/logout', 'UserController.logout')
Then, add the templates :
“resources/views/login.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.login') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Login</button> </form> @endsection
“resources/views/register.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Create new user</button> </form> @endsection
“Controllers/http/UserController.js”
'use strict' const User = use('App/Models/User') class UserController { async create({ request, response, auth }) { const userPayload = request.all(); const user = new User; user.email = userPayload.email; //We will also use the mail as username to simplify things here user.username = userPayload.email; user.password = userPayload.password; await user.save(); await auth.login(user); return response.redirect('/'); } async login({ request, response, auth, session }) { const userPayload = request.all(); try { await auth.attempt(userPayload.email, userPayload.password) } catch (e) { console.log(e); session.flash({ loginError: e }); } return response.redirect('/'); } async logout ({ auth, response }) { await auth.logout(); return response.redirect('/'); } } module.exports = UserController
You can also modify the tasklist template to add the register and login links, and a logout link if the user is logged in.
You can also include the create task form into the loggedIn conditionnal, in order to prevent anonymous users to create tasks.
... @section('content') @loggedIn <a href="logout">Log out</a> @else <a href="login">Log in</a> <a href="register">Register</a> @endloggedIn ...
More features
We now have seen what a basic and naive approach to build a web app can look like. You might have thought about a lot of other features to include in the project. Here is a quick list of other things Adonis can provide to you :
Relations between models
You want the tasks to be owned by users, you can create relations between models with the following syntax :
class User { tasks () { return this.hasMany('App/Model/Task'[, primaryKey, foreignKey]) } }
You can also use hasOne, belongsTo, belongsToMany and manyThrough.
Validators
You can use validators to check is the data flowing into your controllers has the right format, and emit messages (via session.flash for instance) when some errors occurs.
Validators are a 3rd party npm module : https://www.npmjs.com/package/adonis-validator
Using websocket instead of HTTP requests
As you might have seen when creating controllers, you can also generate controllers that are designed to use websockets.
Internationalization
A full guide to make you app multilanguage is available on the Adonis docs as well :
Conclusion
Adonis is a great choice for those who need a full-featured web server framework, and who need to keep control over your implementation.
This framework could be of a great use if you want to kickstart a project, if you want to follow usual guidelines and concepts. It will help you to implement data migrations, keep your code clean, handle data validation…
However, integrating exotic libraries can be painful. Adonis extensions need to be specifically built for this framework. This would be perfect for Adonis and it’s users if the framework would be in a monopoly situation, which is not the case.
Hire Node.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom web app using Node.js, please visit our technology page.
Content Source:
- blog.sourcerer.io