Comment faire un CRUD sur ionic 4 avec local Storage
Comme dans tous autres langage de programmation, faire un crud reste le chose facile a réaliser. Dans articles nous allons voir comment faire un crud sur Ionic 4, Angular 7. Retenons ici que les opérations d’un crud sont les suivantes créer – lire – modifier – supprimer.
Le localStorage est une librairie utilisé sur les applications Angular pour leur permettre de stocker des informations en local. Elle fonctionne sur le principe de clé – valeur et est très utilisé pour faire des sauvegardes.
Nous allons créer notre projet qui sera constitué d’une page qui listera les différents éléments enregistrés dans notre base de donnée. Puis une autre pages qui nous servira de formulaire de création et modifications d’élements enregistrés dans notre base de donnée.
#1: Création du projet et installation du plugin localStorage
Tout d’abord nous allons commencé par créer notre projet en ce servant de la commande suivante :
$ ionic start ion-crud blank
Ensuite nous allons installer les librairies Ionic et cordova du plugin localStorage en utilisant les commandes ci-dessous:
$ ionic cordova plugin add cordova-sqlite-storage $ npm install --save @ionic/storage
Cependant après avoir créé exécuter ces commandes, nous allons modifier la structure de notre projet. Rangeant ainsi nos pages dans le répertoire pages, les providers dans répertoire providers, les modals dans un répertoire modals etc .
D’où après restructuration de notre projet, nous avons arborescente suivante dans notre répertoire src
Après la reforme de notre l’arboressence de notre projet, le fichier src/app/app-routing.module.ts deviendra ce ci :
import { NgModule } from '@angular/core'; import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; const routes: Routes = [ {path: '', loadChildren: './pages/home/home.module#HomePageModule'}, ]; @NgModule({ imports: [ RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) ], exports: [RouterModule] }) export class AppRoutingModule { }
Avant de commencer à créer nos pages, nous allons d’abord configurer le fichier src/app/app-module.ts. Le but ici étant de déclarer notre plugin de localStorage qui permettra de sauvegarder nos données. Après la mise à jour de ce fichier on aura :
import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {RouteReuseStrategy} from '@angular/router'; import {IonicModule, IonicRouteStrategy} from '@ionic/angular'; import {SplashScreen} from '@ionic-native/splash-screen/ngx'; import {StatusBar} from '@ionic-native/status-bar/ngx'; import {AppComponent} from './app.component'; import {AppRoutingModule} from './app-routing.module'; import {FormModule} from './modals/form/form.module'; import {IonicStorageModule} from '@ionic/storage'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [BrowserModule, IonicModule.forRoot(), IonicStorageModule.forRoot({ name: '__mydb', driverOrder: ['indexeddb', 'sqlite', 'websql'] }), AppRoutingModule, FormModule], providers: [ StatusBar, SplashScreen, {provide: RouteReuseStrategy, useClass: IonicRouteStrategy} ], bootstrap: [AppComponent] }) export class AppModule { }
- __mydb représente le nom de notre base de données;
- ‘indexeddb’, ‘sqlite’, ‘websql: représentent les différents type de SGBD sur lesquelles notre application pourra sauvegarder ses données.
#2: Création d’un provider
Un provider est une classe utilisé pour communique avec un flux de donnée. Il rend également disposition le contenu d’une variable dans les différents composant d’une application. Pour créer un provider sur ionic vous pouvez créer une classe typeScript (.ts), ou utiliser la commande suivante pour la générer $ ionic g service nom-du-provider.
rovider. Dans le carde de notre projet nous allons créer notre provider avec cette commande :
$ ionic g service providers/dataProvider
Après cette commande notre fichier src/app/providers/data-provider.service.ts :
import {Injectable} from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DataProviderService { constructor() { } }
Nous allons créer dans notre provider 2 fonctions qui sont:
- loadData() qui cette fonction là qui nous permettra de lire les données dans notre base de donnée
- updateData() qui aura pour objectif de mettre à jour les informations dans notre base de données
C’est dans ce provider que nous allons importer le localStorage qui sera exploité par les précédentes fonctions. Cette importation ce fait par la déclaration de la classe Storage dans les paramètre du constructeur du provider. Le code complet de notre provider est le suivant :
import {Injectable} from '@angular/core'; import {Storage} from '@ionic/storage'; @Injectable({ providedIn: 'root' }) export class DataProviderService { data = []; constructor(private storage: Storage) { } loadData() { return this.storage.get('data').then(value => { if (value) { this.data = JSON.parse(value); } }); } updateData() { this.storage.set('data', JSON.stringify(this.data)); } }
Au démarrage de notre application, les informations qui sont stockées dans la base de données sont chargées dans la variable data. Ce chargement se déroule dans le fichier src/app/app.component.ts. Ce fichier contient la première classe qui est lancé quand on démarre une application Ionic. Elle se fait par l’importation de la classe DataProviderService :
import {Component} from '@angular/core'; import {Platform} from '@ionic/angular'; import {SplashScreen} from '@ionic-native/splash-screen/ngx'; import {StatusBar} from '@ionic-native/status-bar/ngx'; import {DataProviderService} from './providers/data-provider.service'; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.scss'] }) export class AppComponent { constructor( private platform: Platform, private dataProviderService: DataProviderService, private splashScreen: SplashScreen, private statusBar: StatusBar ) { this.initializeApp(); dataProviderService.loadData(); } initializeApp() { this.platform.ready().then(() => { this.statusBar.styleDefault(); this.splashScreen.hide(); }); } }
#3: Mise à jour la page d’accueil
Nous allons nous rendre dans le répertoire pages (src/app/pages) puis nous allons modifier notre page d’accueil (src/app/pages/home).
Dans le fichier src/app/pages/home/home.page.ts nous allons: déclarer notre provider afin de pouvoir accéder aux données stockés par notre application:DataProviderService; Déclarer la classe ModalController pour la gestion des pages modales; Puis déclarer la classe ToastController pour la gestion des messages de notifications; En fin déclarer aussi la classe AlertController pour la gestion des boites de dialogues.
import {Component} from '@angular/core'; import {AlertController, ModalController, ToastController} from '@ionic/angular'; import {DataProviderService} from '../../providers/data-provider.service'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage { constructor(private modalController: ModalController, public alertController: AlertController, public toastController: ToastController, public dataProviderService: DataProviderService) { } }
Toujours dans notre fichier src/app/pages/home/home.page.ts ; Nous allons ajouter une ensemble de fonctions qui permettrons de faire les opérations sur les données stockées dans notre base de données. Ces fonctions sont:
- openModal(data=null) : Cette fonction nous permettra d’ouvrir notre formulaire de création d’un item, en lui passant les paramètres au cas où nous avons à faire a une modification :
async openModal(data = null) { const modal = await this.modalController.create({ component: FormModal, componentProps: {data: data}, animated: true }); return await modal.present(); }
- deleteItem(index) : Cette fonction prend en paramètre l’index du fichier à supprimer et afficher une boite de confirmation à l’utilisateur avant de supprimer l’item en fonction de la réponse de l’utilisateur :
async deleteItem(index) { const alert = await this.alertController.create({ header: 'Supprimer!', message: 'Voullez vous vraiment supprimer?', buttons: [ { text: 'Annuler', role: 'cancel', cssClass: 'secondary', handler: (blah) => { } }, { text: 'Supprimer', handler: () => { this.dataProviderService.data.splice(index, 1); this.dataProviderService.updateData(); this.deleteMessage(); } } ] }); await alert.present(); } async deleteMessage() { const toast = await this.toastController.create({ message: 'Item correctement supprimé', duration: 2000 }); toast.present(); }
La fonction deleteMessage() affiche un message après la suppression de l’item
Le code complet du fichier src/app/pages/home/home.page.ts est le suivant :
import {Component} from '@angular/core'; import {AlertController, ModalController, ToastController} from '@ionic/angular'; import {FormModal} from '../../modals/form/form.modal'; import {DataProviderService} from '../../providers/data-provider.service'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage { constructor(private modalController: ModalController, public alertController: AlertController, public toastController: ToastController, public dataProviderService: DataProviderService) { } async deleteItem(index) { const alert = await this.alertController.create({ header: 'Supprimer!', message: 'Voullez vous vraiment supprimer?', buttons: [ { text: 'Annuler', role: 'cancel', cssClass: 'secondary', handler: (blah) => { } }, { text: 'Supprimer', handler: () => { this.dataProviderService.data.splice(index, 1); this.dataProviderService.updateData(); this.deleteMessage(); } } ] }); await alert.present(); } async deleteMessage() { const toast = await this.toastController.create({ message: 'Item correctement supprimé', duration: 2000 }); toast.present(); } async openModal(data = null) { const modal = await this.modalController.create({ component: FormModal, componentProps: {data: data}, animated: true }); return await modal.present(); } }
Dans le fichier src/app/pages/home/home.page.html, nous allons afficher le contenue du tableau data que nous avons déclaré dans notre DataProviderService :
<ion-header> <ion-toolbar color="primary"> <ion-title> Ion Curd </ion-title> </ion-toolbar> </ion-header> <ion-content> <div > <ion-list *ngIf="dataProviderService.data.length>0"> <ion-list-header> Liste de items </ion-list-header> <ion-item-sliding *ngFor="let d of dataProviderService.data; let i=index "> <ion-item-options side="start"> <ion-item-option (click)="deleteItem(i)" color="danger" expandable> Supprimer </ion-item-option> </ion-item-options> <ion-item (click)="openModal({data:d,index:i})"> <div> <div class="title">{{d.title}}</div> <div class="desc">{{d.desc}}</div> </div> </ion-item> </ion-item-sliding> </ion-list> <div *ngIf="dataProviderService.data.length<1" class="empty-item"> <span> Liste vide</span> </div> </div> <ion-fab vertical="bottom" horizontal="end" slot="fixed"> <ion-fab-button (click)="openModal()"> <ion-icon name="add"></ion-icon> </ion-fab-button> </ion-fab> </ion-content>
Le fichier src/app/pages/home/home.page.scss contient quelques styles de mise en forme qui sont définis pour le fichier home.page.html
ion-content { .empty-item { text-align: center; margin-top: 65%; } ion-list { ion-item { .title { font-size: 15px; font-weight: bold; } .desc { margin-top: 10px; margin-bottom: 10px; font-style: italic; font-size: 13px; } } } }
#4: Création du formulaire de création et de modification
Dans le répertoire src/app/modals nous allons créer une page de type modale nommé form qui sera lancé depuis le clic sur le bouton situé sur la page d’accueil de notre application, elle permettra d’ajouter et modifier les données dans notre base de données :
Nous allons créer le fichier src/app/modals/form/form.module.ts exactement comme dans le cas d’une page. Nous allons importer la classe ReactiveFormsModule qui nous permettra d’appliquer les contrôles instantanés sur notre formulaire.
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import { RouterModule } from '@angular/router'; import { FormModal } from './form.modal'; @NgModule({ imports: [ CommonModule, FormsModule, IonicModule, ReactiveFormsModule, RouterModule.forChild([ { path: '', component: FormModal } ]) ], declarations: [FormModal] }) export class FormModule {}
Puis nous allons créer le fichier src/app/modals/form/form.modal.ts dans lequel nous allons déclarer les fonctions. Ces fonctions nous permettrons de gérer notre formulaire d’insertion et de modification des nos items.
import {Component, OnInit} from '@angular/core'; import {ModalController, NavParams, ToastController} from '@ionic/angular'; import {DataProviderService} from '../../providers/data-provider.service'; import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; @Component({ selector: 'app-form', templateUrl: 'form.modal.html', styleUrls: ['form.modal.scss'], }) export class FormModal implements OnInit { onForm: FormGroup; itemData: any = {data: {title: '', desc: ''}, index: -1}; constructor(private modalController: ModalController, private formBuilder: FormBuilder, private navParams: NavParams, public toastController: ToastController, public dataProviderService: DataProviderService) { if (navParams.data.data) { this.itemData = navParams.data.data; } } async closeModal() { await this.modalController.dismiss(''); } ngOnInit(): void { this.onForm = this.formBuilder.group({ title: new FormControl(this.itemData.data.title, Validators.required), desc: new FormControl(this.itemData.data.desc) }); } saveData() { if (this.itemData.index !== -1) { // @ts-ignore this.dataProviderService.data[this.itemData.index] = this.onForm.value; } else { // @ts-ignore this.dataProviderService.data.push(this.onForm.value); } this.dataProviderService.updateData(); this.updateMessage(); this.closeModal(); } async updateMessage() { const toast = await this.toastController.create({ message: 'Item correctement enregistré', duration: 2000 }); toast.present(); } }
Dans ce fichier nous avons la fonction saveData() qui permet de faire les mises à jours et les insertions dans notre base de donnée.
Nous allons créer un fichier src/app/modals/form/form.modal.html qui est notre vue qui contient notre formulaire
<ion-header> <ion-toolbar color="primary"> <ion-buttons slot="start"> <ion-button (click)="closeModal()"> <ion-icon class="close-icon" name="close"></ion-icon> </ion-button> </ion-buttons> <ion-title>{{itemData.index != -1 ? 'Modifier' : 'Ajouter'}} un item</ion-title> </ion-toolbar> </ion-header> <ion-content> <div padding> <form [formGroup]="onForm" class="list-form"> <ion-item> <ion-label position="floating" color="primary">Titre</ion-label> <ion-input type="text" formControlName="title" placeholder="Titre"></ion-input> </ion-item> <ion-item> <ion-label position="floating" color="primary">Description</ion-label> <ion-textarea formControlName="desc"></ion-textarea> </ion-item> <ion-button expand="block" (click)="saveData()" [disabled]="!onForm.valid" fill="outline" color="primary"> Enregistrer </ion-button> </form> </div> </ion-content>
En fin dans nous allons créer le fichier src/app/modals/form/form.modal.scss qui contiendra les mises en formes ci-dessous
ion-content { ion-button { margin-top: 15px; } }
Le but de cet article était de vous apprendre à créer une application mobile sur ionic 4 qui fait un crud en exploitant une base de donnée local (localStorage). Cette connaissance sur l’exploitation du localStorage pour stocker les informations en local est très important dans les cas de:
- Sauvegarde des informations de configuration d’une applications;
- Synchronisation des informations locales vers un serveur distant ;
- etc.