Dylan  Iqbal

Dylan Iqbal

1560823129

Adonis 4 Tutorial - Learn Adonis 4 in this Crash Course

AdonisJS is basically a clone of the popular PHP-based Laravel framework. The difference however comes when you consider Adonis is based on Node.js. If you're familiar with Laravel and the MVC approach to development, learning Adonis will be a breeze.


Let’s get started!


Installation

First, you’re going to need to install the Adonis CLI in your command line or console:

> npm i --global @adonisjs/cli

Then, hop into your preferred projects folder and run the following command:

> adonis new jobpostr

jobpostr is the name of our app.

After completion, issue the following commands:

> cd jobpostr
> adonis serve --dev

Great! You should now be able to visit your project in the browser at http://127.0.0.1:3333/


Adonis Templating (The View in MVC)

Open up the jobpostr folder your preferred code editor.

First, you might wonder where the template and graphics are coming from when you viewed the site in the browser. We know from the URL that the route is the home route / so, let’s find out where that’s taken care of.

Open up /start/routes.js and you will notice the following code:

const Route = use('Route')
Route.on('/').render('welcome')

This is telling Adonis that when the root of the site is loaded, render a template/view called welcome.

That welcome template can be found in /resources/views/welcome.edge. Here, you will find the associated HTML for the page you see in your browser.

Also notice on line 6 we have this code:

  {{ style('style') }}

That’s a quick and easy Adonis helper function that allows you to reference CSS files with the style() function. It’s referencing a CSS file called style, which can be found in /public/style.css.

For now, let’s focus on the view and structuring out how our views will be situated with a navigation and content section.

Rename welcome.edge to index.edge and create a new folder in /resources/views called layouts with a file inside of it called main.edge.

main.edge will be responsible for storing the head information and the basic layout that we’re going to use. This will help us avoid html duplication.

Inside main.edge, paste the following contents:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    {{ style('style') }}
@!section('extracss')

&lt;title&gt;
    @!section('title')
&lt;/title&gt;

</head>
<body>
<header>
<a href=“/” id=“logo”>JobPostr</a>
<nav>
<ul>
<li><a href=“/”>Jobs</a></li>
<li><a href=“/login”>Login</a></li>
<li><a href=“/signup”>Signup</a></li>
</ul>
</nav>
</header>

&lt;div class="container"&gt;
    @!section('content')
&lt;/div&gt;

</body>
</html>

A few things are happening here, but most importantly, we see @!section(‘title’) and content. Both of these are placeholders, and are therefore dynamic. We can define these content sections in the other edge templates, and their contents will be placed inside of these placeholders.

The extracss section will be used later when we create additional edge templates that require additional CSS imports.

Open our index.edge file and paste the following:

@layout(‘layouts.main’)

@section(‘title’)
JobPostr - Post your Jobs
@endsection

@section(‘content’)
<h1>All Jobs</h1>

<div class=“job-container”>
<div class=“blank”></div>
<div class=“job-info”>
<h3>Job Title</h3>
<p>Future job description can go here.</p>
</div>
</div>
@endsection

First, we tell the edge system to use the layouts.main edge file, and then we define our sections that are defined within main.edge. For now, we don’t have anything dynamic, so the job listing information is simply static. But we’ll come back to that later.

Next, visit the /start/routes.js file and update line 18 to:

Route.on(‘/’).render(‘index’)

Refresh the browser, and you will see our content. But everything looks really ugly right now, so let’s fix that by stepping into public/style.css and pasting the following content:

@import url(‘https://fonts.googleapis.com/css?family=Montserrat:300,700’);

html, body {
height: 100%;
width: 100%;
}

body {
font-family: ‘Montserrat’, sans-serif;
font-weight: 300;
background-color: #EFEFEF;
}

  • {
    margin: 0;
    padding: 0;
    }
    ul {
    list-style-type: none;
    }

header {
background-color: #303C49;
display: grid;
grid-template-columns: 30% auto;
}
header a {
color: white;
text-decoration: none;
text-transform: uppercase;
}
#logo {
font-weight: bold;
font-size: 1.3em;
padding: 1.5em 0 0 2em;
margin: 0;
}
nav {
justify-self: right;
}
nav ul li {
display: inline;
}
nav ul li a {
padding: 2em;
display: inline-block;
}
nav ul li a:hover {
background: #455668;
}
.container {
width: calc(100% - 4em);
padding: 2em;
margin-top: 2em;
}
h1 {
margin-bottom: 1em;
}
.job-container, .job-container2 {
background: white;
border-radius: 7px;
padding: 1em;
margin-bottom: 10px;
display: grid;
grid-template-columns: 120px auto;
}
.blank {
width: 100px;
height: 100px;
border: 1px solid lightgray;
border-radius: 5px;
}

It’s quite a bit, but nothing special is happening here. This is what the result should look like in the browser after refreshing:

Great!


Databases

Now that we’ve touched on some of the View related stuff, let’s talk about the backend stuff. Adonis 5 supports the following databases to store your data:

  • PostgreSQL
  • SQLite
  • MySQL
  • MariaDB
  • Oracle
  • MSSQL

For this tutorial, we’re going to use MySQL. This will require installing MySQL on your machine if you plan to develop locally. I won’t be covering how to get this set up and running, so, perform some Google searches on installing MySQL if you have a hard time.

Visit the /.env file and change DB_CONNECTION to mysql: along with setting the database to jobpostr:

DB_CONNECTION=mysql
DB_DATABASE=jobpostr

This will tell Adonis that we want to use MySQL as our database.

Next, let’s use the command line to install mysql:

> adonis install mysql

Now, we have to create the jobpostr database in the command line. After installing MySQL and ensuring you have access to the mysql command from the command line, type:

> mysql -u root -p
:: hit enter when prompted for a password ::

mysql> create database jobpostr;
mysql> exit;

After running the final command, our database will be created.

If you installed MySQL Workbench and open it up, you wil see the new jobpostr database listed in your databases!

Next, how do we actually populate this database with tables, data and such? That’s done with the help of Adonis Migrations.


Migrations

Migration files allow you to create and delete tables.

Open up /database/migrations and you will see two migrations already created. Open up the _user.js migration file.

You will see we have both and up() and down() method. Up is for creating or altering a table of some sort, and down is for rolling back the changes made in Up.

The way we run these migrations is through the console:

> adonis migration:run

output:

migrate: 1503248427885_user.js
migrate: 1503248427886_token.js
Database migrated successfully in 613 ms

If you use MySQL workbench of the mysql command line tool, you will see that our database now has 3 tables. One for users, tokens, and schemas. The schemas table keeps track of which database migrations were ran!

Let’s make a new migration with the Adonis CLI for storing our job posting data:

> adonis make:migration jobs
> Choose an action Create table
√ create database\migrations\1536680712439_jobs_schema.js

When prompted, choose create table and hit enter.

This results in a new migrations file being created in the /database/migrations folder. Open up the new file and update the following section:

    this.create(‘jobs’, (table) => {
table.increments()
table.string(‘title’)
table.string(‘link’)
table.string(‘description’)
table.integer(‘user_id’)
table.timestamps()
})

Here, we’re adding 4 columns called title, link, description, user_id. The user_id field will allow us to keep track of who posted which job.

Let’s run this migration file now:

> adonis migration:run
migrate: 1536680712439_jobs_schema.js
Database migrated successfully in 313 ms

If you view the database, you will now see the new table!


Creating a Model

Now that our database and tables have been created, we need to create a model for handling our jobs table and associated data.

Let’s use the Adonis CLI to create a new model for Jobs data:

> adonis make:model Job

Open up /app/Models/Job.js and you will see the following code:

‘use strict’

const Model = use(‘Model’)

class Job extends Model {
}

module.exports = Job

Notice the naming convention. I chose Job because that’s the naming convention used for a table named in the plural context jobs. You will notice the same thing for the User model and the users table.

At this point, we don’t have to do anything else with our Model. As long as it’s created, we’ve done our job.


Creating a Controller

Next, we need to define a controller that’s responsible for using the Job model for creating, altering and retreiving jobs from the database.

Let’s use the Adonis CLI to create that controller:

> adonis make:controller JobController
> Select controller type
> For HTTP requests
For Websocket channel

Choose “For HTTP requests” and hit enter.

Open up /app/Controllers/Http/JobController.js and specify the following:

‘use strict’

const Job = use(‘App/Models/Job’)

class JobController {
async home({view}) {

    // Create a job
    const job = new Job;
    job.title = 'My job title';
    job.link = 'http://google.com';
    job.description = 'My job description';

    await job.save();

    // Fetch a job
    const jobs = await Job.all();

    return view.render('index', { jobs: jobs.toJSON() })
}

}

module.exports = JobController

Here, we’re first creating a job when someone visits the / route. This is just temporary and will allow us to insert a row of data into our table. Then, we’re fetching all of the jobs. This is all made possible by referencing our Model.

At the end we’re returning the view of index (index.edge) and passing the jobs to the view.

In order for this to work, we need to modify the /start/routes.js file:

Route.get(‘/’, ‘JobController.home’);

Save this, and then visit the browser and refresh the home page. Then, view the data shown in MySQL and you will see the new data inserted into the table!

Let’s modify our /resources/views/index.edge to display the returned data:

  @each(job in jobs)
<div class=“job-container”>
<div class=“blank”></div>
<div class=“job-info”>
<h3><a href=“{{ job.link }}”>{{ job.title }}</a></h3>
<p>{{ job.description }}</p>
</div>
</div>
@endeach

Awesome! Now, view the result in the browser:

Let’s remove the create command from the controller:

class JobController {
async home({view}) {

    // Fetch a job
    const jobs = await Job.all();

    return view.render('index', { jobs: jobs.toJSON() })
}

}

User Authentication

Before we can allow users to submit jobs, we need to create a user authentication system with a signup and login.

Fortunately, our users table and model has already been created for us.

Let’s visit the routes.js file and add the following 2 lines to the bottom:

Route.on(‘/signup’).render(‘auth.signup’);
Route.on(‘/login’).render(‘auth.login’);

This is referencing a couple views that don’t yet exist, so create the following folder and file structure:

/resources
/views
/auth
login.edge
signup.edge

Inside signup.edge paste the following HTML:

@layout(‘layouts.main’)

@section(‘extracss’)
{{ style(‘forms’) }}
@endsection

@section(‘title’)
JobPostr - Sign up
@endsection

@section(‘content’)
<h1>Join now</h1>

<div class=“job-container”>
<form action=“{{ route(‘UserController.create’) }}” method=“POST”>
{{ csrfField() }}

    &lt;label for="username"&gt;Username&lt;/label&gt;
    &lt;input type="text" name="username" value="{{ old('username', '') }}"&gt;
    @if(hasErrorFor('username'))
        &lt;span&gt;
            {{ getErrorFor('username') }}
        &lt;/span&gt;
    @endif

    &lt;label for="email"&gt;Email&lt;/label&gt;
    &lt;input type="email" name="email" value="{{ old('email', '') }}"&gt;
    @if(hasErrorFor('email'))
        &lt;span&gt;
            {{ getErrorFor('email') }}
        &lt;/span&gt;
    @endif

    &lt;label for="password"&gt;Password&lt;/label&gt;
    &lt;input type="password" name="password"&gt;
    @if(hasErrorFor('password'))
        &lt;span&gt;
            {{ getErrorFor('password') }}
        &lt;/span&gt;
    @endif

    &lt;button type="submit"&gt;Join now&lt;/button&gt;
  &lt;/form&gt;

</div>
@endsection

A few things are happening here:

  • First, notice we’re using the style(‘forms’) function at the top. This means we need to create a CSS file, we’ll do this in the next step…
  • In the form tag, we’re setting the action attribute to an Adonis helper function called Route, which means it will submit the route to a method called Create in our UserController. We will create this method shortly…
  • We’re using csrfField() to generate a hidden input to ensure this request is coming from our server.
  • In two of the inputs, we use the Adonis old() function to persist form data if an error shows up during future form validation.
  • We use the Adonis helper function hasErrorFor(‘field’) to display errors returned from form validation.

Let’s create a file in: /public/forms.css and paste the following CSS:

.job-container {
grid-template-columns: auto;
padding: 2em;
width: 30%;

}
label {
font-weight: bold;
}
input[type=‘text’], input[type=‘email’], input[type=‘password’] {
width: calc(100% - 4em);
display: block;
padding: .5em;
margin-bottom: 20px;
border: 2px solid lightgray;
}
/* Change the white to any color ;) */
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 30px white inset;
}

button {
padding: .5em;
background: #455668;
border: 0;
color: white;
font-size: 1.2em;
font-family: ‘Montserrat’;
text-transform: uppercase;
font-weight: bold;
border-radius: 5px;
margin-top: 20px;
cursor: pointer;
}

span {
display: block;
background: yellow;
padding: .3em;
margin-bottom: 20px;
}

The result in the browser should now look like this:

Visit the routes.js file and add a post line underneath the first line shown here:

Route.on(‘/signup’).render(‘auth.signup’);
Route.post(‘/signup’, ‘UserController.create’).validator(‘CreateUser’);

Notice that we’re adding a .validator() at the end? This will allow us to validate the form data submitted before it reaches the create method in the controller.

Let’s install the validator plugin with the Adonis CLI:

> adonis install @adonisjs/validator

Once installed, open up /start/app.js and we’ll add the validator as a provider in the providers array:

const providers = [
‘@adonisjs/framework/providers/AppProvider’,
‘@adonisjs/framework/providers/ViewProvider’,
‘@adonisjs/lucid/providers/LucidProvider’,
‘@adonisjs/bodyparser/providers/BodyParserProvider’,
‘@adonisjs/cors/providers/CorsProvider’,
‘@adonisjs/shield/providers/ShieldProvider’,
‘@adonisjs/session/providers/SessionProvider’,
‘@adonisjs/auth/providers/AuthProvider’,
‘@adonisjs/validator/providers/ValidatorProvider’ // Add here
]

Now, we’ve gained access to an Adonis CLI command to create a custom validator:

> adonis make:validator CreateUser

This creates a file (open it up) in: /app/Validators/CreateUser.js. Paste the following contents:

‘use strict’

class CreateUser {
get rules () {
return {
‘username’: ‘required|unique:users’,
‘email’: ‘required|unique:users’,
‘password’: ‘required’
}
}

get messages() {
return {
‘required’: ‘Woah now, {{ field }} is required.’,
‘unique’: ‘Wait a second, the {{ field }} already exists’
}
}

async fails(error) {
this.ctx.session.withErrors(error)
.flashAll();

return this.ctx.response.redirect('back');

}
}

module.exports = CreateUser

First, we define the rules() for each of the form data that’s to be submitted. Next, we create validation messages in case any of the fields that are required or unique end up failing.

Then, in the case of a failure (async fails()), we flash a message to the session, which will be displayed by our view.

Save this, and try submitting the form without specifying any data!

We need to create a controller that will allow us to issue commands to the predefined User model, which interacts with the users table in our database:

> adonis make:controller UserController

(Choose HTTP request).

In the /app/Controllers/UserController.js file, paste the following:

‘use strict’

const User = use(‘App/Models/User’);

class UserController {
async create({ request, response, auth}) {
const user = await User.create(request.only([‘username’,‘email’,‘password’]));

    await auth.login(user);
    return response.redirect('/');
}

}

module.exports = UserController

First, we’re defining a constant for the User model, then we create the create() method in which we specify the request, response and auth from the context.

Then we use User.create() to create the user, then log them in, and redirect them back to the home page!

Give it a shot! Visit the signup page, fill out the form correctly, and then view your MySQL Users table. It should show the new user.


Logged in status

Right now, our user is logged in, but it’s not being reflected in the view. Let’s make an adjustment for that.

Visit the /resources/views/layouts/main.edge file and modify the nav section:

        <nav>
<ul>
<li><a href=“/”>Jobs</a></li>
@loggedIn
<li><a href=“/post-a-job”>My Jobs</a></li>
<li><a href=“/logout”>Logout</a></li>
@else
<li><a href=“/login”>Login</a></li>
<li><a href=“/signup”>Signup</a></li>
@endloggedIn
</ul>
</nav>

Simple enough! Refresh the browser and you should see the @loggedIn links.


Logging Out

Logging out is very simple. Visit the routes file and paste the following at the bottom of the file:

Route.get(‘/logout’, async ({ auth, response }) => {
await auth.logout();
return response.redirect(‘/’);
});

If you refresh and click logout in the navigation, you will be logged out!

Awesome!


Logging In

Visit the /auth/login.edge file and paste the following contents:

@layout(‘layouts.main’)

@section(‘extracss’)
{{ style(‘forms’) }}
@endsection

@section(‘title’)
JobPostr - Login
@endsection

@section(‘content’)
<h1>Login now</h1>

<div class=“job-container”>
@if(flashMessage(‘loginError’))
<span>{{ flashMessage(‘loginError’) }}</span>
@endif
<form action=“{{ route(‘UserController.login’) }}” method=“POST”>
{{ csrfField() }}

    &lt;label for="email"&gt;Email&lt;/label&gt;
    &lt;input type="email" name="email" value="{{ old('email', '') }}"&gt;
    @if(hasErrorFor('email'))
        &lt;span&gt;
            {{ getErrorFor('email') }}
        &lt;/span&gt;
    @endif

    &lt;label for="password"&gt;Password&lt;/label&gt;
    &lt;input type="password" name="password"&gt;
    @if(hasErrorFor('password'))
        &lt;span&gt;
            {{ getErrorFor('password') }}
        &lt;/span&gt;
    @endif

    &lt;button type="submit"&gt;Login now&lt;/button&gt;
  &lt;/form&gt;

</div>
@endsection

It’s almost identical to the signup.edge with just a few differences.

Visit the routes.js file and add the following route:

Route.post(‘/login’, ‘UserController.login’).validator(‘LoginUser’);

Now, let’s create a new validator with the Adonis CLI:

> adonis make:validator LoginUser

Open up the /app/Validators/LoginUser.js and paste the following:

‘use strict’

class CreateUser {
get rules () {
return {
‘email’: ‘required|email’,
‘password’: ‘required’
}
}

get messages() {
return {
‘required’: ‘Woah now, {{ field }} is required.’,
}
}

async fails(error) {
this.ctx.session.withErrors(error)
.flashAll();

return this.ctx.response.redirect('back');

}
}

module.exports = CreateUser

It’s almost identical to the CreateUser.js validator.

In /app/Controllers/Http/UserController.js add the following just underneath the create() {} method:

    async login({ request, auth, response, session }) {
const { email, password } = request.all();

    try {
        await auth.attempt(email, password);
        return response.redirect('/');
    } catch (error) {
        session.flash({loginError: 'These credentials do not work.'})
        return response.redirect('/login');
    }
}

This will take the email and password submitted from the request, and auth.attempt() to login. If successful, we return them to the home page. If not, it will flash a session message called loginError which is being displayed by our edge view.

Give it a shot. Try logging in with the user you created before and it should work. Great!


Posting Jobs

Now that we can create users and login, let’s take a look at posting jobs.

Create a new edge view file: /resources/views/jobs.edge and paste the following:

@layout(‘layouts.main’)

@section(‘title’)
JobPostr - Post your Job
@endsection

@section(‘extracss’)
{{ style(‘forms’) }}
@endsection

@section(‘content’)
<h1>Post a Job</h1>

<div class=“job-container”>
@if(flashMessage(‘message’))
<span>{{ flashMessage(‘message’) }}</span>
@endif
<form action=“{{ route(‘JobController.create’) }}” method=“POST”>
{{ csrfField() }}

      &lt;label for="title"&gt;Job Title&lt;/label&gt;
      &lt;input type="text" name="title" value="{{ old('title', '') }}"&gt;
      @if(hasErrorFor('title'))
          &lt;span&gt;
              {{ getErrorFor('title') }}
          &lt;/span&gt;
      @endif

      &lt;label for="link"&gt;Link URL&lt;/label&gt;
      &lt;input type="text" name="link" value="{{ old('link', '') }}"&gt;
      @if(hasErrorFor('link'))
          &lt;span&gt;
              {{ getErrorFor('link') }}
          &lt;/span&gt;
      @endif

      &lt;label for="description"&gt;Description&lt;/label&gt;
      &lt;input type="text" name="description"&gt;
      @if(hasErrorFor('description'))
          &lt;span&gt;
              {{ getErrorFor('description') }}
          &lt;/span&gt;
      @endif

      &lt;button type="submit"&gt;Submit a Job&lt;/button&gt;
    &lt;/form&gt;
&lt;/div&gt;

<h2>My jobs</h2>

@each(job in jobs)
<div class=“job-container2”>
<div class=“blank”></div>
<div class=“job-info”>
<h3><a href=“{{ job.link }}”>{{ job.title }}</a></h3>
<p>{{ job.description }}</p>
<ul>
<li><a href=“{{ route(‘JobController.delete’, { id: job.id }) }}”>Delete</a></li>
<li><a href=“{{ route(‘JobController.edit’, { id: job.id }) }}”>Edit</a></li>
</ul>
</div>
</div>
@endeach
@endsection

Next, let’s create a relationship between the user and jobs. We do this by opening up the app/Models/User.js file and class model, paste:

  jobs() {
return this.hasMany(‘App/Models/Job’);
}

This will allow our controller to automatically append the currently logged in user’s ID to new job postings.

Let’s create a new validator for our jobs:

> adonis make:validator CreateJob

Open up the new CreateJob.js validator and specify the following:

‘use strict’

class CreateJob {
get rules () {
return {
title: ‘required’,
link: ‘required’
}
}
get messages() {
return {
‘required’: ‘Hold up, the {{ field }} is required.’
}
}

async fails(error) {
this.ctx.session.withErrors(error)
.flashAll();

return this.ctx.response.redirect('back');

}
}

module.exports = CreateJob

Next, open up routes.js and add the following routes:

Route.get(‘/post-a-job’, ‘JobController.userIndex’);
Route.get(‘/post-a-job/delete/:id’, ‘JobController.delete’);
Route.get(‘/post-a-job/edit/:id’, ‘JobController.edit’);
Route.post(‘/post-a-job/update/:id’, ‘JobController.update’).validator(‘CreateJob’);

These routes are all for defining CRUD (Create Read Update and Delete) functionality.

Open up the JobController.js file and add the following methods:

    async userIndex({view, auth}) {

    // Fetch all user's jobs
    const jobs = await auth.user.jobs().fetch();
    console.log(jobs)

    return view.render('jobs', { jobs: jobs.toJSON() })
}

async create({ request, response, session, auth}) {
    const job = request.all();

    const posted = await auth.user.jobs().create({
        title: job.title,
        link: job.link,
        description: job.description
    });

    session.flash({ message: 'Your job has been posted!' });
    return response.redirect('back');
}

async delete({ response, session, params}) {
    const job = await Job.find(params.id);

    await job.delete();
    session.flash({ message: 'Your job has been removed'});
    return response.redirect('back');
}

async edit({ params, view }) {
    const job = await Job.find(params.id);
    return view.render('edit', { job: job });
}

async update ({ response, request, session, params }) {
    const job = await Job.find(params.id);

    job.title = request.all().title;
    job.link = request.all().link;
    job.description = request.all().description;

    await job.save();

    session.flash({ message: 'Your job has been updated. '});
    return response.redirect('/post-a-job');
}

Save this and give it a shot by posting a new job! The new job should be posted directly underneath the form.

You can also click the Delete link and it should work as well.

In order to make the edit link work, we have to create a new edge view.

Create the file /resources/views/edit.edge when the following template:

@layout(‘layouts.main’)

@section(‘title’)
JobPostr - Edit your Job
@endsection

@section(‘extracss’)
{{ style(‘forms’) }}
@endsection

@section(‘content’)
<h1>Edit Job</h1>

<div class=“job-container”>
@if(flashMessage(‘message’))
<span>{{ flashMessage(‘message’) }}</span>
@endif
<form action=“{{ route(‘JobController.update’, { id: job.id }) }}” method=“POST”>
{{ csrfField() }}

      &lt;label for="title"&gt;Job Title&lt;/label&gt;
      &lt;input type="text" name="title" value="{{ job.title }}"&gt;
      @if(hasErrorFor('title'))
          &lt;span&gt;
              {{ getErrorFor('title') }}
          &lt;/span&gt;
      @endif

      &lt;label for="link"&gt;Link URL&lt;/label&gt;
      &lt;input type="text" name="link" value="{{ job.link }}"&gt;
      @if(hasErrorFor('link'))
          &lt;span&gt;
              {{ getErrorFor('link') }}
          &lt;/span&gt;
      @endif

      &lt;label for="description"&gt;Description&lt;/label&gt;
      &lt;input type="text" name="description" value="{{ job.description }}"&gt;
      @if(hasErrorFor('description'))
          &lt;span&gt;
              {{ getErrorFor('description') }}
          &lt;/span&gt;
      @endif

      &lt;button type="submit"&gt;Update Job&lt;/button&gt;&lt;br&gt;
    &lt;/form&gt;
&lt;/div&gt;

@endsection

Save this and try clicking edit on an existing job and then editing it.


Refactoring the Routes

Right now, this section is rather redundant / verbose:

Route.get(‘/post-a-job’, ‘JobController.userIndex’);
Route.get(‘/post-a-job/delete/:id’, ‘JobController.delete’);
Route.get(‘/post-a-job/edit/:id’, ‘JobController.edit’);
Route.post(‘/post-a-job/update/:id’, ‘JobController.update’).validator(‘CreateJob’);

We can simplify this a bit by using Route Groups. Modify it as such:

Route.get(‘/post-a-job’, ‘JobController.userIndex’);

Route.group(() => {
Route.get(‘/delete/:id’, ‘JobController.delete’);
Route.get(‘/edit/:id’, ‘JobController.edit’);
Route.post(‘/update/:id’, ‘JobController.update’).validator(‘CreateJob’);
}).prefix(‘/post-a-job’);

Conclusion

We’ve just scratched the surface here, but hopefully this should get you going to the point at which you have some solid footing to learn even more!

#javascript #angular #node-js #reactjs

What is GEEK

Buddha Community

Adonis 4 Tutorial - Learn Adonis 4 in this Crash Course
Sival Alethea

Sival Alethea

1624395600

MongoDB with Python Crash Course - Tutorial for Beginners. DO NOT MISS!!!

Learn the most popular NoSQL / document database: MongoDB. In this quickstart tutorial, you’ll be up and running with MongoDB and Python.
⭐️Course Contents⭐️
⌨️ (0:00:00) Welcome
⌨️ (0:04:33) Intro to MongoDB
⌨️ (0:07:49) How do document DBs work?
⌨️ (0:10:34) Who uses MongoDB
⌨️ (0:13:02) Data modeling
⌨️ (0:16:30) Modeling guidelines
⌨️ (0:22:11) Integration database
⌨️ (0:24:23) Getting demo code
⌨️ (0:30:07) How ODMs work?
⌨️ (0:32:55) Introduction to mongoengine
⌨️ (0:34:01) Demo: Registering connections with MongoEngine
⌨️ (0:37:20) Concept: Registering connections
⌨️ (0:39:14) Demo: Defining mongoengine entities (classes)
⌨️ (0:45:22) Concept: mongoengine entities
⌨️ (0:49:03) Demo: Create a new account
⌨️ (0:56:55) Demo: Robo 3T for viewing and managing data
⌨️ (0:58:18) Demo: Login
⌨️ (1:00:07) Demo: Register a cage
⌨️ (1:10:28) Demo: Add a bookable time as a host
⌨️ (1:16:13) Demo: Managing your snakes as a guest
⌨️ (1:19:18) Demo: Book a cage as a guest
⌨️ (1:33:41) Demo: View your bookings as guest
⌨️ (1:41:29) Demo: View bookings as host
⌨️ (1:46:18) Concept: Inserting documents
⌨️ (1:47:28) Concept: Queries
⌨️ (1:48:09) Concept: Querying subdocuments with mongoengine
⌨️ (1:49:37) Concept: Query using operators
⌨️ (1:50:24) Concept: Updating via whole documents
⌨️ (1:51:46) Concept: Updating via in-place operators
⌨️ (1:54:01) Conclusion

📺 The video in this post was made by freeCodeCamp.org
The origin of the article: https://www.youtube.com/watch?v=E-1xI85Zog8&list=PLWKjhJtqVAbnqBxcdjVGgT3uVR10bzTEB&index=10
🔥 If you’re a beginner. I believe the article below will be useful to you ☞ What You Should Know Before Investing in Cryptocurrency - For Beginner
⭐ ⭐ ⭐The project is of interest to the community. Join to Get free ‘GEEK coin’ (GEEKCASH coin)!
☞ **-----CLICK HERE-----**⭐ ⭐ ⭐
Thanks for visiting and watching! Please don’t forget to leave a like, comment and share!

#mongodb #python #python crash course #mongodb with python crash course - tutorial for beginners #beginners #mongodb with python crash course

Ananya Gupta

1595485129

Pros and Cons of Machine Learning Language

Amid all the promotion around Big Data, we continue hearing the expression “AI”. In addition to the fact that it offers a profitable vocation, it vows to tackle issues and advantage organizations by making expectations and helping them settle on better choices. In this blog, we will gain proficiency with the Advantages and Disadvantages of Machine Learning. As we will attempt to comprehend where to utilize it and where not to utilize Machine learning.

In this article, we discuss the Pros and Cons of Machine Learning.
Each coin has two faces, each face has its property and highlights. It’s an ideal opportunity to reveal the essence of ML. An extremely integral asset that holds the possibility to reform how things work.

Pros of Machine learning

  1. **Effectively recognizes patterns and examples **

AI can survey enormous volumes of information and find explicit patterns and examples that would not be evident to people. For example, for an online business site like Amazon, it serves to comprehend the perusing practices and buy chronicles of its clients to help oblige the correct items, arrangements, and updates pertinent to them. It utilizes the outcomes to uncover important promotions to them.

**Do you know the Applications of Machine Learning? **

  1. No human mediation required (mechanization)

With ML, you don’t have to keep an eye on the venture at all times. Since it implies enabling machines to learn, it lets them make forecasts and improve the calculations all alone. A typical case of this is hostile to infection programming projects; they figure out how to channel new dangers as they are perceived. ML is additionally acceptable at perceiving spam.

  1. **Constant Improvement **

As ML calculations gain understanding, they continue improving in precision and productivity. This lets them settle on better choices. Let’s assume you have to make a climate figure model. As the measure of information you have continues developing, your calculations figure out how to make increasingly exact expectations quicker.

  1. **Taking care of multi-dimensional and multi-assortment information **

AI calculations are acceptable at taking care of information that is multi-dimensional and multi-assortment, and they can do this in unique or unsure conditions. Key Difference Between Machine Learning and Artificial Intelligence

  1. **Wide Applications **

You could be an e-posterior or a social insurance supplier and make ML work for you. Where it applies, it holds the ability to help convey a considerably more close to home understanding to clients while additionally focusing on the correct clients.

**Cons of Machine Learning **

With every one of those points of interest to its effectiveness and ubiquity, Machine Learning isn’t great. The accompanying components serve to confine it:

1.** Information Acquisition**

AI requires monstrous informational indexes to prepare on, and these ought to be comprehensive/fair-minded, and of good quality. There can likewise be times where they should trust that new information will be created.

  1. **Time and Resources **

ML needs sufficient opportunity to allow the calculations to learn and grow enough to satisfy their motivation with a lot of precision and pertinence. It additionally needs monstrous assets to work. This can mean extra necessities of PC power for you.
**
Likewise, see the eventual fate of Machine Learning **

  1. **Understanding of Results **

Another significant test is the capacity to precisely decipher results produced by the calculations. You should likewise cautiously pick the calculations for your motivation.

  1. High mistake weakness

AI is self-governing yet exceptionally powerless to mistakes. Assume you train a calculation with informational indexes sufficiently little to not be comprehensive. You end up with one-sided expectations originating from a one-sided preparing set. This prompts unessential promotions being shown to clients. On account of ML, such botches can set off a chain of mistakes that can go undetected for extensive periods. What’s more, when they do get saw, it takes very some effort to perceive the wellspring of the issue, and significantly longer to address it.

**Conclusion: **

Subsequently, we have considered the Pros and Cons of Machine Learning. Likewise, this blog causes a person to comprehend why one needs to pick AI. While Machine Learning can be unimaginably ground-breaking when utilized in the correct manners and in the correct spots (where gigantic preparing informational indexes are accessible), it unquestionably isn’t for everybody. You may likewise prefer to peruse Deep Learning Vs Machine Learning.

#machine learning online training #machine learning online course #machine learning course #machine learning certification course #machine learning training

Sival Alethea

Sival Alethea

1624305600

Learn Data Science Tutorial - Full Course for Beginners. DO NOT MISS!!!

Learn Data Science is this full tutorial course for absolute beginners. Data science is considered the “sexiest job of the 21st century.” You’ll learn the important elements of data science. You’ll be introduced to the principles, practices, and tools that make data science the powerful medium for critical insight in business and research. You’ll have a solid foundation for future learning and applications in your work. With data science, you can do what you want to do, and do it better. This course covers the foundations of data science, data sourcing, coding, mathematics, and statistics.
⭐️ Course Contents ⭐️
⌨️ Part 1: Data Science: An Introduction: Foundations of Data Science

  • Welcome (1.1)
  • Demand for Data Science (2.1)
  • The Data Science Venn Diagram (2.2)
  • The Data Science Pathway (2.3)
  • Roles in Data Science (2.4)
  • Teams in Data Science (2.5)
  • Big Data (3.1)
  • Coding (3.2)
  • Statistics (3.3)
  • Business Intelligence (3.4)
  • Do No Harm (4.1)
  • Methods Overview (5.1)
  • Sourcing Overview (5.2)
  • Coding Overview (5.3)
  • Math Overview (5.4)
  • Statistics Overview (5.5)
  • Machine Learning Overview (5.6)
  • Interpretability (6.1)
  • Actionable Insights (6.2)
  • Presentation Graphics (6.3)
  • Reproducible Research (6.4)
  • Next Steps (7.1)

⌨️ Part 2: Data Sourcing: Foundations of Data Science (1:39:46)

  • Welcome (1.1)
  • Metrics (2.1)
  • Accuracy (2.2)
  • Social Context of Measurement (2.3)
  • Existing Data (3.1)
  • APIs (3.2)
  • Scraping (3.3)
  • New Data (4.1)
  • Interviews (4.2)
  • Surveys (4.3)
  • Card Sorting (4.4)
  • Lab Experiments (4.5)
  • A/B Testing (4.6)
  • Next Steps (5.1)

⌨️ Part 3: Coding (2:32:42)

  • Welcome (1.1)
  • Spreadsheets (2.1)
  • Tableau Public (2.2)
  • SPSS (2.3)
  • JASP (2.4)
  • Other Software (2.5)
  • HTML (3.1)
  • XML (3.2)
  • JSON (3.3)
  • R (4.1)
  • Python (4.2)
  • SQL (4.3)
  • C, C++, & Java (4.4)
  • Bash (4.5)
  • Regex (5.1)
  • Next Steps (6.1)

⌨️ Part 4: Mathematics (4:01:09)

  • Welcome (1.1)
  • Elementary Algebra (2.1)
  • Linear Algebra (2.2)
  • Systems of Linear Equations (2.3)
  • Calculus (2.4)
  • Calculus & Optimization (2.5)
  • Big O (3.1)
  • Probability (3.2)

⌨️ Part 5: Statistics (4:44:03)

  • Welcome (1.1)
  • Exploration Overview (2.1)
  • Exploratory Graphics (2.2)
  • Exploratory Statistics (2.3)
  • Descriptive Statistics (2.4)
  • Inferential Statistics (3.1)
  • Hypothesis Testing (3.2)
  • Estimation (3.3)
  • Estimators (4.1)
  • Measures of Fit (4.2)
  • Feature Selection (4.3)
  • Problems in Modeling (4.4)
  • Model Validation (4.5)
  • DIY (4.6)
  • Next Step (5.1)

📺 The video in this post was made by freeCodeCamp.org
The origin of the article: https://www.youtube.com/watch?v=ua-CiDNNj30&list=PLWKjhJtqVAblfum5WiQblKPwIbqYXkDoC&index=7
🔺 DISCLAIMER: The article is for information sharing. The content of this video is solely the opinions of the speaker who is not a licensed financial advisor or registered investment advisor. Not investment advice or legal advice.
Cryptocurrency trading is VERY risky. Make sure you understand these risks and that you are responsible for what you do with your money
🔥 If you’re a beginner. I believe the article below will be useful to you ☞ What You Should Know Before Investing in Cryptocurrency - For Beginner
⭐ ⭐ ⭐The project is of interest to the community. Join to Get free ‘GEEK coin’ (GEEKCASH coin)!
☞ **-----CLICK HERE-----**⭐ ⭐ ⭐
Thanks for visiting and watching! Please don’t forget to leave a like, comment and share!

#data science #learn data science #learn data science tutorial #beginners #learn data science tutorial - full course for beginners

Sival Alethea

Sival Alethea

1624291780

Learn Python - Full Course for Beginners [Tutorial]

This course will give you a full introduction into all of the core concepts in python. Follow along with the videos and you’ll be a python programmer in no time!
⭐️ Contents ⭐
⌨️ (0:00) Introduction
⌨️ (1:45) Installing Python & PyCharm
⌨️ (6:40) Setup & Hello World
⌨️ (10:23) Drawing a Shape
⌨️ (15:06) Variables & Data Types
⌨️ (27:03) Working With Strings
⌨️ (38:18) Working With Numbers
⌨️ (48:26) Getting Input From Users
⌨️ (52:37) Building a Basic Calculator
⌨️ (58:27) Mad Libs Game
⌨️ (1:03:10) Lists
⌨️ (1:10:44) List Functions
⌨️ (1:18:57) Tuples
⌨️ (1:24:15) Functions
⌨️ (1:34:11) Return Statement
⌨️ (1:40:06) If Statements
⌨️ (1:54:07) If Statements & Comparisons
⌨️ (2:00:37) Building a better Calculator
⌨️ (2:07:17) Dictionaries
⌨️ (2:14:13) While Loop
⌨️ (2:20:21) Building a Guessing Game
⌨️ (2:32:44) For Loops
⌨️ (2:41:20) Exponent Function
⌨️ (2:47:13) 2D Lists & Nested Loops
⌨️ (2:52:41) Building a Translator
⌨️ (3:00:18) Comments
⌨️ (3:04:17) Try / Except
⌨️ (3:12:41) Reading Files
⌨️ (3:21:26) Writing to Files
⌨️ (3:28:13) Modules & Pip
⌨️ (3:43:56) Classes & Objects
⌨️ (3:57:37) Building a Multiple Choice Quiz
⌨️ (4:08:28) Object Functions
⌨️ (4:12:37) Inheritance
⌨️ (4:20:43) Python Interpreter
📺 The video in this post was made by freeCodeCamp.org
The origin of the article: https://www.youtube.com/watch?v=rfscVS0vtbw&list=PLWKjhJtqVAblfum5WiQblKPwIbqYXkDoC&index=3

🔥 If you’re a beginner. I believe the article below will be useful to you ☞ What You Should Know Before Investing in Cryptocurrency - For Beginner
⭐ ⭐ ⭐The project is of interest to the community. Join to Get free ‘GEEK coin’ (GEEKCASH coin)!
☞ **-----CLICK HERE-----**⭐ ⭐ ⭐
Thanks for visiting and watching! Please don’t forget to leave a like, comment and share!

#python #learn python #learn python for beginners #learn python - full course for beginners [tutorial] #python programmer #concepts in python

Biju Augustian

Biju Augustian

1574943719

Learn JavaScript Crash Course | Best Javascript Tutorial

Description
So you need to learn Javascript and learn it fast!

Are you a designer who’s now adding JavaScript to your knowledge arsenal? Are you a student who needs a fast and high-quality JavaScript course? Are you a traditional developer trying to learn the basics? Are you applying for a job that requires JavaScript.

JavaScript is not only emerging as the most important language to know, it’s flexibility is unique. With JavaScript being deployed on the web, mobile and even the desktop this is the one language that all technologists need to know. As a JavaScript developer you’ll find opportunity around every corner!

This is a crash course meaning it moves quick. Every meaningful lecture is chock full of information that you can immediately apply to your coding work. Taught by a master instructor, you’ll find that Javascript: Crash Course is a extremely efficient way to learn.

Each lecture course lecture includes the actual code developed by the master instructor during the lecture. No more staring at a blank screen when figuring out how to practice use the included code as a starting point.

The course culminates with developing a full quiz application called Trivia. You’ll learn from building out this application yourself and modifying it and making it your own!

Join the over 500,000 learners who’ve enjoyed LearnToProgram courses. At LearnToProgram, we’re teaching the world to code!

Who is the target audience?

Newbies Who Want to Learn Javascript Quickly
Current Programmers who need a Crash Course in Javascript
Those with Limited Time who Want to Learn Alot
Teacher and Students
Designers and Developers who Want to Learn JavaScript Efficiently
Basic knowledge
Foundational HTML
Text editor
Web Browser
What will you learn
Understand and write Javascript Code
Run Javascript Code in a Browser
Choose and Utilize Tools Used by Professional Javascript Developers
Understand the Purpose of Javascript Variables
Declare and Initialize Javascript Variables
User Variables with Strings and Numbers
Perform Mathematical Operations with Javascript
Obtain input from the User via Alert Boxes
Obtain input from the User via Forms
Understand Simple Conditionals with If
Create Complex Conditionals with If Else If
Create While Loops
Create For Loops
Understand the Purpose and Power of Javascript Objects
Use Event Objects to Track Events that Occur
Use the Javscript Date Object to Track Dates
Use the Javascript String Object to Manipulate Strings
Include Audio and Video Content with the Media API
Use the XMLHttpRequest() Object to Exchange Data
Create a Basic Ajax Request
Parse JSON code

#JavaScript #Crash Course #Tutorial