Build Crud App With Nodejs -Angular -PostgreSql

Baiklah temen-temen disini saya saya akan mengimplementasikan pembuatan aplikasi sederhana yaitu aplikasi crud.yang saya buat dengan BeckEnd : NodeJS(ExpressJs), dengan FrontEnd : AngularJS dan menggunakan Database PostgreSql.

Ok,langsung saja ya temen-temen mari kita mulai :D.

Make BeckEnd

Kita mulai dengan penginstall express:

$ npm install -g express-generator@4.13.4

Langkah selanjutnya kita buat Aplikasinya dan lanjut kita install Packagenya :

$ express nodeJs-postgres-todo
$ cd nodeJs-postgres-todo && npm install

Selanjutnya saya menggunakan Package SuperVisor Untuk melihat Perubahan pada Code Saya berikut adalah Cara penginstallanya:

$ npm install supervisor@0.11.0 -g

Jangan lupa temen-update Update file Package.json seperti berikut:

"scripts": {
"start": "supervisor ./bin/www"
},

Ok dan Langsung saja kita run dengan cara :

$ npm start

Aplikasi Express Langsung otomatis Akan menavigate Kedalam Localhost:3000 di browser.

Setup Pada PostgreSql :

Jika Postgre temen-temen Sudah berjalan Pada Port 5432, Pembuatan koneksi database menjadi mudah dengan pg library:

$ npm install pg@6.1.0 --save

Dan sekarang kita tinggal buat Tabel Pada Script Kita :

const pg = require('pg');
const connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/todo';

const client = new pg.Client(connectionString);
client.connect();
const query = client.query(
'CREATE TABLE items(id SERIAL PRIMARY KEY, text VARCHAR(40) not null, complete BOOLEAN)');
query.on('end', () => { client.end(); });

Save Coding Diatas di Folder Model dan berikan nama dengan database.js ,setelah itu mari kita coba jalankan dengan cara

$ node models/database.js

Verifikasi scema tabel dalam database kita:

$ psql
#\c todo
You are now connected to database "todo" as user "rikisetiyopambudi".
todo=# \d items
Table "public.items"
Column | Type | Modifiers
----------+-----------------------+----------------------------------------------------
id | integer | not null default nextval('items_id_seq'::regclass)
text | character varying(40) | not null
complete | boolean |
Indexes:
"items_pkey" PRIMARY KEY, btree (id)

todo=#

Dengan pengaturan Configurasi kita dapat membuat operai Crud:

Pembuatan Server-side:Router

Disini Kita hanya menambahkan end point pada Index.js Pada folder Route:

const express = require('express');
const router = express.Router();
const pg = require('pg');
const path = require('path');
const connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/todo';

Sekarang Kita tambahkan endpointnya:

Fuctions:
1. CREAT :Kita buat dengan /api/v1/todos

2. READ :Kita buat dengan api/v1/todos

3. UPDATE:Kita buat dengan /api/v1/todos/:todo_id

4. DELETE:Kita buat dengan /api/v1/todos/:todo_id

Selanjutnya kita Buat semua Funtions diatas dengan tutorial coding saya dibawah ini:

CREAT

router.post('/api/v1/todos', (req, res, next) => {
const results = [];
// Grab data from http request
const data = {text: req.body.text, complete: false};
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Insert Data
client.query('INSERT INTO items(text, complete) values($1, $2)',
[data.text, data.complete]);
// SQL Query > Select Data
const query = client.query('SELECT * FROM items ORDER BY id ASC');
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', () => {
done();
return res.json(results);
});
});
});

READ

router.get('/api/v1/todos', (req, res, next) => {
const results = [];
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Select Data
const query = client.query('SELECT * FROM items ORDER BY id ASC;');
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', () => {
done();
return res.json(results);
});
});
});

Update

router.put('/api/v1/todos/:todo_id', (req, res, next) => {
const results = [];
// Grab data from the URL parameters
const id = req.params.todo_id;
// Grab data from http request
const data = {text: req.body.text, complete: req.body.complete};
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Update Data
client.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)',
[data.text, data.complete, id]);
// SQL Query > Select Data
const query = client.query("SELECT * FROM items ORDER BY id ASC");
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', function() {
done();
return res.json(results);
});
});
});

router.put('/api/v1/todos/:todo_id', (req, res, next) => {
const results = [];
// Grab data from the URL parameters
const id = req.params.todo_id;
// Grab data from http request
const data = {text: req.body.text, complete: req.body.complete};
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Update Data
client.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)',
[data.text, data.complete, id]);
// SQL Query > Select Data
const query = client.query("SELECT * FROM items ORDER BY id ASC");
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', function() {
done();
return res.json(results);
});
});
});

router.put('/api/v1/todos/:todo_id', (req, res, next) => {
const results = [];
// Grab data from the URL parameters
const id = req.params.todo_id;
// Grab data from http request
const data = {text: req.body.text, complete: req.body.complete};
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Update Data
client.query('UPDATE items SET text=($1), complete=($2) WHERE id=($3)',
[data.text, data.complete, id]);
// SQL Query > Select Data
const query = client.query("SELECT * FROM items ORDER BY id ASC");
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', function() {
done();
return res.json(results);
});
});
});

Delete

router.delete('/api/v1/todos/:todo_id', (req, res, next) => {
const results = [];
// Grab data from the URL parameters
const id = req.params.todo_id;
// Get a Postgres client from the connection pool
pg.connect(connectionString, (err, client, done) => {
// Handle connection errors
if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}
// SQL Query > Delete Data
client.query('DELETE FROM items WHERE id=($1)', [id]);
// SQL Query > Select Data
var query = client.query('SELECT * FROM items ORDER BY id ASC');
// Stream results back one row at a time
query.on('row', (row) => {
results.push(row);
});
// After all data is returned, close connection and return results
query.on('end', () => {
done();
return res.json(results);
});
});
});

Sekarang kita masuk Refactoring:

Client-Side: Angular

Module

Temen-temen disini Buat file App.js Dalam folder “public/javascripts”.

angular.module('nodeTodo', [])
.controller('mainController', ($scope, $http) => {
$scope.formData = {};
$scope.todoData = {};
// Get all todos
$http.get('/api/v1/todos')
.success((data) => {
$scope.todoData = data;
console.log(data);
})
.error((error) => {
console.log('Error: ' + error);
});
});

Update Main Route

Update file index.js dan kita sambungkan pada router kita:

router.get('/', (req, res, next) => {
res.sendFile('index.html');
});

View

Sekarang kita buat Basic angularnya di file index.html:

<!DOCTYPE html>
<html ng-app="nodeTodo">
<head>
<title>Todo App - with Node + Express + Angular + PostgreSQL</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body ng-controller="mainController">
<div class="container">
<ul ng-repeat="todo in todoData">
<li>{{ todo.text }}</li>
</ul>
</div>
<script src="//code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.min.js"></script>
<script src="javascripts/app.js"></script>
</body>
</html>

tambahkan file kedalam folder public.

Selanjutnya kita update module kita:

// Pembuatan
$scope.createTodo = () => {
$http.post('/api/v1/todos', $scope.formData)
.success((data) => {
$scope.formData = {};
$scope.todoData = data;
console.log(data);
})
.error((error) => {
console.log('Error: ' + error);
});
};
// Penghapusan
$scope.deleteTodo = (todoID) => {
$http.delete('/api/v1/todos/' + todoID)
.success((data) => {
$scope.todoData = data;
console.log(data);
})
.error((data) => {
console.log('Error: ' + data);
});
};

dan jangan lupa kita update coding kita seperti berikut:
<li><input type="checkbox" ng-click="deleteTodo(todo.id)">&nbsp;{{ todo.text }}</li>

dan kita buat form:

<div class="container">
<form>
<div class="form-group">
<input type="text" class="form-control input-lg" placeholder="Add a todo..." ng-model="formData.text">
</div>
<button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add Todo</button>
</form>
<ul ng-repeat="todo in todoData">
<li><input type="checkbox" ng-click="deleteTodo(todo.id)">&nbsp;{{ todo.text }}</li>
</ul>
</div>

semua fungsi utama selesai mari kita perbaiki bagian depan agar terlihat rapi :

HTML:

<!DOCTYPE html>
<html ng-app="nodeTodo">
<head>
<title>Todo App - with Node + Express + Angular + PostgreSQL</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" href="/stylesheets/style.css" media="screen">
</head>
<body ng-controller="mainController">
<div class="container">
<div class="header">
<h1>Todo App</h1>
<hr>
<h1 class="lead">Node + Express + Angular + PostgreSQL</h1>
</div>
<div class="todo-form">
<form>
<div class="form-group">
<input type="text" class="form-control input-lg" placeholder="Enter text..." ng-model="formData.text">
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block" ng-click="createTodo()">Add Todo</button>
</form>
</div>
<br>
<div class="todo-list">
<ul ng-repeat="todo in todoData">
<li><h3><input class="lead" type="checkbox" ng-click="deleteTodo(todo.id)">&nbsp;{{ todo.text }}</h3></li><hr>
</ul>
</div>
</div>
<script src="//code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.min.js"></script>
<script src="javascripts/app.js"></script>
</body>
</html>

Css:

body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
color: #00B7FF;
}

ul {
list-style-type: none;
padding-left: 10px;
}

.container {
max-width: 400px;
background-color: #eeeeee;
border: 1px solid black;
}

.header {
text-align: center;
}

Ok temen-temen bisa Lihat structure aplikasinya seperti dibawah ini:

├── app.js
├── bin
│ └── www
├── client
│ ├── javascripts
│ │ └── app.js
│ ├── stylesheets
│ │ └── style.css
│ └── views
│ └── index.html
├── package.json
└── server
├── models
│ └── database.js
└── routes
└── index.js

Sekarang kita buat Code Update:

server/routes/index.js:

router.get('/', (req, res, next) => {
res.sendFile(path.join(
__dirname, '..', '..', 'client', 'views', 'index.html'));
});

app.js

const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');

const routes = require('./server/routes/index');

const app = express();

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'client')));

app.use('/', routes);


app.use((req, res, next) => {
var err = new Error('Not Found');
err.status = 404;
next(err);
});


if (app.get('env') === 'development') {
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: err
});
});
}


app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: {}
});
});


module.exports = app;

Apakah temen-temen melihat banyak kesamaan pada setiap codingan:
pg.connect(connectionString, (err, client, done) => {

if(err) {
done();
console.log(err);
return res.status(500).json({success: false, data: err});
}

const query = client.query('SELECT * FROM items ORDER BY id ASC;');

query.on('row', (row) => {
results.push(row);
});

query.on('end', () => {
done();
return res.json(results);
});
});

Ok temen-temen mungkin seperti itu tutorial dari saya temen-temen boleh req seputar nodejs pada comment dibawah

https://rikisetiyopambudi.herokuapp.com/

Riki Setiyo Pambudi

Written by

Iam Fullstack Developer, Based in Jakarta Indonesia…https://riki-setiyo-pambudi.herokuapp.com/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade