Loading

MongoDB Oak Deno Angular means MODA Stack

MongoDB Oak Deno Angular means MODA Stack

Hello and welcome to all the Deno loving peoples around the world. Hope you guys are enjoying a lot and learned new things from our articles.

Haven't got a chance to review our previous articles? Here is a quick links for your easy reference.

We already covers following topics in Deno,

Today, we will talk about MongoDB, Oak, Deno and Angular in short MODA. Now please share your thoughts about the term MODA. Sounds crazy right. Let's popular this term.

So, all good. We will now see how we can achieve MODA. The first component of MODA is Mongodb. Lets see what we can write in Mongodb part.

import { MongoClient } from "https://deno.land/x/mongo/mod.ts";

const client=new MongoClient();
client.connectWithUri("mongodb://localhost:27017");
const db = client.database("moda");
const student = db.collection("student");

export { db, student };

After creating the mongo part now move to Oak. For that lets create the server.ts

import { Application, Router } from "https://deno.land/x/oak/mod.ts";
import { oakCors } from "https://deno.land/x/cors/mod.ts";
import { allStudents, addStudent, updateStudent, deleteStudent, studentById } from "./controller.ts";

const PORT = 8000;
const app=new Application();
const router=new Router();

router
    .get("/students", allStudents)
    .get("/student/:id", studentById)
    .post("/student", addStudent)
    .put("/student/:id", updateStudent)
    .delete("/student/:id", deleteStudent);


app.use(oakCors());
app.use(router.routes());
app.use(router.allowedMethods());
console.log("Server is running in port:", PORT);  
app.listen({port: PORT});

After creating the server.ts we need to prepare the controller. So here is the controller.ts

import { student } from './mongo.ts';

export const allStudents = async (context: any) => {
    try {
        let data=await student.find({});
        context.response.body={ data: data };
        context.response.status=200;
    }
    catch (error) {
        context.response.body={ error, data: [] };
        context.response.status=400
    }
}
export const studentById = async (context: any) => {
    try {
        const id :string = context.params.id;
        let data = await student.findOne({ _id: { "$oid": id } });
        context.response.body={ success:true, data: data };
        context.response.status=200;
    }
    catch (error) {
        context.response.body={ error, data: {} };
        context.response.status=400
    }
}
export const addStudent = async (context: any) => {
    try {
        const body =  context.request.body();
        const stud_value = await body.value;

        const id = await student.insertOne(stud_value);    
        context.response.body={success:true, id: id };
        context.response.status=200;
    }
    catch (error) {
        context.response.body={ error, id: "" };
        context.response.status=400
    }
}
export const updateStudent = async (context: any) => {
    try {
        const id :string = context.params.id;
        const body =  context.request.body();
        const stud_value = await body.value;

        const data = await student.updateOne({ _id: { "$oid": id } }, { $set: stud_value });   
        context.response.body={ success:true, data: data };
        context.response.status=200;
    }
    catch (error) {
        context.response.body={ error, data: "" };
        context.response.status=400
    }
}
export const deleteStudent=async (context: any) => {
    try {
        const id :string = context.params.id;
        const data = await student.deleteOne({_id: {"$oid": id}});  
        context.response.body={ success:true,  data: data };
        context.response.status=200;
    }
    catch (error) {
        context.response.body={ error, data: "" };
        context.response.status=400
    }
}

Well, upto this deno part is ready now we have focus on frontend that we will do with Angular. In frontend, we will see the important files required in this case. First we will the app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';
import { StudentService } from './app.service';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [StudentService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now we need to see the service class. Here is the app.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class StudentService {

    baseUrl = "http://localhost:8000";
    constructor(public http: HttpClient) { }

    allStudents(){
        return this.http.get(this.baseUrl + '/students');
    }
    addStudent(student:any){
        let url = this.baseUrl + '/student';
        return this.http.post(url, student);
    }
    updateStudent(student: any) {
        let url = this.baseUrl + '/student/'+ student._id.$oid;
        delete student["_id"];
        let body = student;
        return this.http.put(url, body);
    }
    deleteStudent(id:any){
        let url = this.baseUrl + '/student/'+ id;
        return this.http.delete(url);
    }

}

After creating the app.service.ts we will now look at

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { StudentService } from './app.service';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    openform = false;
    openList = true;
    title='Mongo Oak Deno Angular, simply MODA';
    sub: Subscription;
    students: any=[];
    student: any={ id: 0, name: "", price: "", color: "", size:"" };
    editFlag=false;
    constructor(private studentService: StudentService) { }

    ngOnInit() {
        this.getStudents();
    }
    onAddStudentSubmit() {
        if (this.editFlag==false) {
            this.sub=this.studentService.addStudent(this.student).subscribe((data: any) => {
                if (data.success == true) {
                    this.getStudents();
                    this.resetForm();
                    this.openform = false;
                    this.openList = true;
                }
                else {
                    console.log("Failed");
                }
            });
        }
        else {
            this.sub=this.studentService.updateStudent(this.student).subscribe((data: any) => {
                if (data.success) {
                    this.getStudents();
                    this.resetForm();
                    this.openform = false;
                    this.openList = true;
                }
                else {
                    console.log("Failed");
                }
            });
        }

    }

    onEditStudent(id: any, s_students: any) {
        this.openform = true;
        this.openList = false;
        this.student = JSON.parse(JSON.stringify(s_students))
        this.editFlag=true;
    }

    onDeleteStudent(pId: number) {
        this.sub=this.studentService.deleteStudent(pId).subscribe((data: any) => {
            if (data.success) {
                this.getStudents();
            }
            else {
                console.log("Failed");
            }
        });
    }

    resetForm() {
        this.student={ id: 0, name: "", price: "", color: "", size:"" };
        this.editFlag=false;
    }

    ngOnDestroy() {
        this.sub.unsubscribe();
    }

    private getStudents() {
        this.sub=this.studentService.allStudents().subscribe((data: any) => {
            this.students=data.data;
        });

    }

    onClickOpenForm(){
      this.openform = true;
      this.openList = false;
    }

    cancelForm() {
      this.openform = false;
      this.openList = true;
    }
}

Finally we will checkout the app.component.html file

<div class="container">
    <div style="text-align:center"><h2>{{title}}</h2></div>
    <br/>
    <div class="row" >
        <div class="col-md-4" style="width: 100%;" [hidden]="!openform" >
            <form name="form" (ngSubmit)="onAddStudentSubmit()" >
                <div class="form-group">
                  <label for="exampleInputEmail1">Student name</label>
                  <input type="text" name="name" [(ngModel)]="student.name" #name="ngModel"  class="form-control" aria-describedby="emailHelp" placeholder="Enter name">

                </div>
                <div class="form-group">
                  <label >Class</label>
                  <input type="text" name="price" [(ngModel)]="student.class" #price="ngModel" class="form-control"  placeholder="Price">
                </div>
                <div class="form-group">
                    <label >Roll No</label>
                    <input type="text" name="color" [(ngModel)]="student.roll" #color="ngModel" class="form-control" placeholder="Color">
                </div>
                <div class="form-group">
                    <label >Dress Size</label>
                    <select id="inputState" name="size" [(ngModel)]="student.dress_size" #size="ngModel" class="form-control">
                        <option value="Small">Small</option>
                        <option value="Medium">Medium</option>
                        <option value="Large">Large</option>
                    </select>
                </div>
                <button   type="submit" *ngIf="editFlag == false" class="btn btn-primary">Add Student</button>
                <button  type="submit" *ngIf="editFlag == true" class="btn btn-primary">Update Student</button>
                <button  type="button"  (click)="cancelForm()" class="btn btn-danger" style="margin-left: 10px">Cancel</button>
              </form>
        </div>
        <div class="col-md-8" style="width: 100%;" [hidden]="!openList">

            <table class="table table-bordered">
                <thead>
                  <tr>
                    <td colspan="6" align="right">
                      <a href="javascript:void()" (click)="onClickOpenForm()" >Add </a>
                    </td>
                  </tr>
                  <tr>
                    <th scope="col">#</th>
                    <th scope="col">Student name</th>
                    <th scope="col">Class</th>
                    <th scope="col">Roll No</th>
                    <th scope="col">Dress Size</th>
                    <th scope="col" style="text-align: center;">Action</th>
                  </tr>
                </thead>
                <tbody>
                    <tr *ngFor="let student of students; let i=index" >
                        <td>{{i+1}}</td>
                        <td>{{student.name}}</td>
                        <td>{{student.class}}</td>
                        <td>{{student.roll}}</td>
                        <td>{{student.dress_size}}</td>
                        <td style="text-align: center;">
                          <a href="javascript:void()" (click)="onEditStudent(student._id.$oid,  student)" >Edit</a> |
                          <a href="javascript:void()" (click)="onDeleteStudent(student._id.$oid)">Delete</a></td>
                      </tr>
                </tbody>
              </table>
        </div>
    </div>
</div>

Cool, all files are ready. Now we have to run the deno file and at the same time we also need to start the frontend.

$ deno run --allow-net --allow-read --allow-write --allow-plugin --unstable server.ts

and to run the frontend part you need to write the following code.

$ npm install
$ ng serve.

Summary

So by the above example we are now clearly understand how MODA stack can be achieved. It's a combination of Mongo, Oak, Deno and Angular.

Please leave a comment at info@codinghub.net and share this article as much as you can. Thank you very much!

We are on Facebook, Twitter, LinkedIn, Medium, Quora, Instagram, etc.

By the way, want to learn more about Deno? Just check out the official Deno documentation.

Related Articles