Ionic 4 Todo Application Using Dynamic Backend APIs From SmartCodehub

javascript Oct 08, 2019

In this article we are going to see how we can create an ionic 4 , angular application with smartcodehub API generation tool.

1) First let's create an ionic project using

ionic start TODOAPPLCAITION

Now open the project in vs code.

2) Secondly visit to start.smartcodehub.com

3) Login with your credential if you have not register then you can register here.

4) After login download the stater kit and open it with vs code and run

npm i

5) Navigate to smartcodehub.com and create a user modal with fields like name , email , password.

Now click on create resources button , but don't click on download button navigate to Models and click on lock icon in front of User model..

You will be able to see drawer like this Now you have select request payloads and token payloads..

like i will send email and password and in response it will give me name and email..

Now click on generate api resources and click the download button shown about the generate button

6) After downloading the zip file extract it and copy the content of zip file accordingly into Express starter like there will be user.controller.js file then you have to copy the file in controller folder.

7) After Copying the files to folder open the instruction file and copy two command to app.js

8) Now get back to models and create a model todo which contains fields like task , date(set its property type to date) and isdone(set its property type to boolean) and click on generate api resources but don't download it navigate to Models and you will see info icon in front of todo model click on it ...

It will open a drawer like this then you have to check the create secure resources and select authenticate entity as user.

If you don't know why i have done this then watch this video here

Now click on generate api resources and download it and copy the zip file content in stater file and follow the instruction file.

9) Now Important thing is that we need to change the secret key in user.controller.js starting with

 const ENV_SECRET_STRING = "Put_A_Secure_string_here_for_token_generation";

You can put anything like TODOAPPLICATIONBYYOURNAME and copy it and paste it in todo.route.js

at

const ENV_SECRET_STRING = "The_String_Present_In_Your_userController";

That's its you api is setup now get back to application

Just the the command

npm start

So that your application starts running on localhost...

first delete the home folder and remove the import from app.module and app.route

after that we need to generate some pages like login , register , todo , createTodo

ionic g page login
ionig g page register
ionic g page todo
ionic g page todo/createTodo

We are using @ionic/storage to save the user email and token  so that we don't need user to log many time as it open application.

ionic cordova plugin add cordova-sqlite-storage

npm install --save @ionic/storage

Now change the line of login in app.route file

/*We have to change this*/

{path: 'login' , loadChildren: './login/login.module#LoginModule' } 

/*to*/

{path: '', loadChildren: './login/login.module#LoginModule' }

and also let's make change like if there is email and token present in storage then the user should navigate to todo page if not then he or she has to register / login accordingly.

constructor(private storage: Storage,
    private route: Router)
    
  
  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      this.storage
        .get('email')
        .then(res => {
          this.route.navigate(['/todo']);
        })
        .catch(err => {
          this.route.navigate(['/']);
        });
    });
  }

And after that just add the following code to your login page

<ion-header>
  <ion-toolbar>
    <ion-title>
      Login
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <ion-card-content>
      <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input [(ngModel)]="email" name="email" type="text"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label position="floating">Password</ion-label>
        <ion-input [(ngModel)]="password" name="password" type="password"></ion-input>
      </ion-item>

      <ion-button expand="block" fill="outline" (click)="login()" color="primary">Login</ion-button>



    </ion-card-content>
    <ion-card-header>
      <ion-button expand="block" fill="outline" [routerLink]="['/register']" color="primary">Register</ion-button>
    </ion-card-header>
  </ion-card>
</ion-content>

in LoginPage .ts file

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Storage } from '@ionic/storage';
import { ToastController } from '@ionic/angular';
import { Router } from '@angular/router';
@Component({
  selector: 'app-login',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss']
})
export class LoginPage {
  email: any;
  password: any;

  constructor(
    private http: HttpClient,
    private storage: Storage,
    private route: Router,
    private toastCtrl: ToastController
  ) {}

  async login() {
    const postData = {
      email: this.email,
      password: this.password
    };

    this.http
      .post(`http://localhost:3332/api/user/login`, postData)
      .subscribe(async (res: any) => {
        this.storage.set('email', this.email);
        this.storage.set('token', res.token);

        const toast = await this.toastCtrl.create({
          message: 'LoggedIn Success.',
          duration: 2500,
          position: 'bottom'
        });
        toast.present();
        this.route.navigate(['/todo']);
      });
  }
}

Now in register page

<ion-header>
  <ion-toolbar>
    <ion-title>Register</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <ion-card-content>
      <ion-item>
        <ion-label position="floating">Name</ion-label>
        <ion-input [(ngModel)]="name" name="name" type="text"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input [(ngModel)]="email" name="email" type="text"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label position="floating">Password</ion-label>
        <ion-input [(ngModel)]="password" name="password" type="password"></ion-input>
      </ion-item>

      <ion-button expand="block" fill="outline" (click)="register()" color="primary">Login</ion-button>



    </ion-card-content>
    <ion-card-header>
      <ion-button expand="block" fill="outline" [routerLink]="['/']" color="primary">Register</ion-button>
    </ion-card-header>
  </ion-card>
</ion-content>

in register.ts file

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Route, Router } from '@angular/router';

@Component({
  selector: 'app-register',
  templateUrl: './register.page.html',
  styleUrls: ['./register.page.scss']
})
export class RegisterPage implements OnInit {
  name: string;
  email: string;
  password: string;

  constructor(private http: HttpClient, private route: Router) {}

  ngOnInit() {}

  register() {
    const postData = {
      name: this.name,
      email: this.email,
      password: this.password
    };

    this.http
      .post('http://localhost:3332/api/user', postData)
      .subscribe(res => {
        this.route.navigate(['/']);
      });
  }
}

Now let's create the todo page

<ion-header>
  <ion-toolbar>
    <ion-title>Create</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <ion-card-content>
      <ion-item>
        <ion-label position="floating">Task</ion-label>
        <ion-input [(ngModel)]="task" name="task" type="text"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label>Date</ion-label>
        <ion-datetime [(ngModel)]="date" name="date" display-format="DD.MM.YYYY HH:mm"></ion-datetime>
      </ion-item>

      <ion-button expand="block" fill="outline" (click)="createTodo()" color="primary">Create</ion-button>
    </ion-card-content>
  </ion-card>
</ion-content>

and in todo-create.page.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Storage } from '@ionic/storage';
import { ToastController } from '@ionic/angular';
import { Router } from '@angular/router';

@Component({
  selector: 'app-create-todo',
  templateUrl: './create-todo.page.html',
  styleUrls: ['./create-todo.page.scss']
})
export class CreateTodoPage implements OnInit {
  task: string;
  date: Date;
  token: string;
  constructor(
    private http: HttpClient,
    private toastCtrl: ToastController,
    private storage: Storage,
    private route: Router
  ) {}

  ngOnInit() {
    this.storage
      .get('token')
      .then(res => {
        this.token = res;
      })
      .catch(async err => {
        const Toast = await this.toastCtrl.create({
          message: 'No Token Found',
          position: 'bottom',
          duration: 2500
        });
        Toast.present();
      });
  }
  createTodo() {
    const headers = {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      Authorization: this.token
    };

    const postDate = {
      task: this.task,
      date: this.date,
      isdone: false
    };
    this.http
      .post('http://localhost:3332/api/todo', postDate, { headers })
      .subscribe(async res => {
        console.log(res);
        const Toast = await this.toastCtrl.create({
          message: 'Todo Create Successfully',
          position: 'bottom',
          duration: 2500
        });
        Toast.present();

        this.route.navigate(['/todo']);
      });
  }
}

Now on todo page file

<ion-header>
  <ion-toolbar>
    <ion-title>Todo</ion-title>
    <ion-buttons slot="end">
      <ion-button [routerLink]="['/create-todo']">
        <ion-icon name="md-add"></ion-icon>
      </ion-button>
    </ion-buttons>
  </ion-toolbar>

</ion-header>

<ion-content>
  
  <ion-item *ngFor="let item of data" (click)="openAlert(item)">
    <ion-label>
      {{item.task}}
    </ion-label>

    <ion-label style="float: right">{{item.date | date}}</ion-label>
  </ion-item>
</ion-content>

Now in todo.page.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Storage } from '@ionic/storage';
import { ToastController, AlertController } from '@ionic/angular';

@Component({
  selector: 'app-todo',
  templateUrl: './todo.page.html',
  styleUrls: ['./todo.page.scss']
})
export class TodoPage implements OnInit {
  token: string;
  data: any;
  constructor(
    private http: HttpClient,
    private storage: Storage,
    private toastCtrl: ToastController,
    private alertCtrl: AlertController
  ) {}

  ngOnInit() {
    console.log('here');
    const headers = {
      'Content-Type': 'application/json',
      Authorization: this.token
    };
    this.storage
      .get('token')
      .then(res => {
        this.token = res;

        this.http
          .get('http://localhost:3332/api/todo', {
            headers: { Authorization: this.token }
          })
          .subscribe(data => {
            this.data = data;
          });
      })
      .catch(async err => {
        const Toast = await this.toastCtrl.create({
          message: 'No Token Found',
          position: 'bottom',
          duration: 2500
        });
        Toast.present();
      });
  }

  async openAlert(item) {
    const alert = await this.alertCtrl.create({
      message: 'Is this task Completed',
      animated: true,
      buttons: [
        {
          text: 'No',
          role: 'cancel',
          cssClass: 'secondary',
          handler: cancel => {
            console.log('Confirm Cancel: blah');
          }
        },
        {
          text: 'Yes',
          handler: () => {
            item.isdone = true;
            this.http
              .put('http://localhost:3332/api/todo/' + item._id, item, {
                headers: { Authorization: this.token }
              })
              .subscribe(async res => {
                const toast = await this.toastCtrl.create({
                  message: 'Todo Completed',
                  duration: 2500,
                  position: 'bottom'
                });
                toast.present();
              });
          }
        }
      ]
    });

    alert.present();
  }
}

That's it just launch it using

ionic serve 
ionic run android 
ionic run ios 

Thanks of reading this article please refer the above links for more info...

https://youtu.be/gOR16Zx0oKE

Abhishek

Hi There! I Am Abhishek Developer, Singer & Photographer. Living In Mumbai. My interests range from technology to entrepreneurship. I am also interested in food, designing, and education.