Contacts Archive - Ionic3

Contacts Archive - Ionic3

Fully functional Ionic 3 app that allows personal contacts management


Daniel Codrea

Daniel Codrea

Member since 2016


iOS, Android  
4 years ago
4 years ago
ionic3, angular4, camera, google calendar, google maps, forms, reactiveForms, save data, display data, edit saved data,

About the app

A simple fully functional personal contacts manager mobile application written in Ionic 3 and Angular 4.

You can save you personal contacts by filling out a simple form. Add details as name, email, phone, date of birth, a short description, and one or more addresses. The only mandatory fields, that also validate, are the “First Name”, "Last Name", and “Email”. You can assign an image to a contact by using the camera or selecting an existing image from the gallery.

There is an example of how to build a custom directive. The example directive is used to generate an avatar for a contact that has no image associated with it.

There is an example of how to create custom pipes. The example is used to transform to HTML break tag the new lines from the saved text area in the contact form.

Each contact from the list of contacts on the all contacts page is slideable and you can call or email the contact, provided the contact has a phone number and/or email address associated with it. These methods are also available on the contact details page.

Also, the contact addresses once tapped will be displayed on a map using the GoogleMaps API.

On the contact details page, the contact date of birth is clickable. Once clicked it can create a Google Calendar yearly repeatable event with the contact's birth date.

The app is built using Ionic v3 and Angular4 and it can be used as both an Android or an iOs app.

2nd version

The app has been updated to use the latest ionic-cli as of July 2017. It has been tested both on MacOS and Win10 systems.

Starting and running the app

After downloading and unpacking the files, simply navigate to the app's folder and "npm install" to get all dependencies. Don't forget to add your desired platform using the "ionic platform add " command.

Extending the app

The application is fully functional and stores the saved contacts to the device's local storage. If you would like to sync the app to a cloud DB, this can be done in a snap. I recommend using the IBM cloudant service. Just edit your contacts.ts file from the services folder as follows:

``` import {Injectable} from '@angular/core'; import PouchDB from 'pouchdb'; PouchDB.plugin(require('pouchdb-find')); PouchDB.plugin(require('pouchdb-quick-search'));

@Injectable() export class ContactsService { private db: any; private success: boolean = true; private remote: any; private username: any; private password: any;

constructor() { this.db = new PouchDB('contacts.db'); if (typeof window != "undefined") { window["PouchDB"] = PouchDB }

this.username = '<DB_USERNAME>';
this.password = '<DB_PASSWORD>';
this.remote = '<DB_URL>';

let options = {
  live: true,
  retry: true,
  continuous: true,
  auth: {
    username: this.username,
    password: this.password

this.db.sync(this.remote, options).on('change', (info) => {
  console.log('Handling syncing change');
}).on('paused', (info) => {
  console.log('Handling syncing pause');
}).on('active', (info) => {
  console.log('Handling syncing resumption');
}).on('denied', (err) => {
  console.log('Handling syncing denied');
}).on('complete', (info) => {
  console.log('Handling syncing complete');
}).on('error', (err) => {
  console.log('Handling syncing error');


handleSyncing() { this.db.changes({ since: 'now', live: true, include_docs: true }).on('change', (change) => { // handle change console.log('Handling change'); console.dir(change); }).on('complete', (info) => { // changes() was canceled console.log('Changes complete'); console.dir(info); }).on('error', (err) => { console.log('Changes error'); console.log(err); }); }

getLimitedNoContacts(name, skip) { return new Promise(resolve => { this.db.createIndex({ index: {fields: ['lastName']} }).then(() => { this.db.find({ selector: { $and: [ {_id: {$exists: true}}, {lastName: {$gte: name}} ] }, limit: 25, skip: skip, sort: [{'lastName': 'asc'}] }).then((result) => { let k, items = [], row =; for (k in row) { var item = row[k]; items.push(item); } resolve(items); }); }); }); }

searchForContacts(name) { return new Promise(resolve => {{ query: "" + name, fields: ['firstName', 'lastName'], include_docs: true }).then((result) => { let k, items = [], row = result.rows; for (k in row) { var item = row[k].doc; items.push(item); } resolve(items); }); }); }

createContact(contact) { return new Promise(resolve => { this.db.put(contact).catch((err) => { console.log('adding contact error is: ', err); this.success = false; }); if (this.success) { this.handleSyncing(); resolve(true); } }); }

getContact(contactId) { return new Promise(resolve => { this.db.get(contactId).then((result) => { let item = []; item.push(result); resolve(item); }).catch((error) => { console.log('getting contact from db error: ', error); }); }); }

updateContact(contact) { return new Promise(resolve => { this.db.put(contact).catch((err) => { console.log('updating contact error: ', err); this.success = false; }); if (this.success) { this.handleSyncing(); resolve(true); } }) }

deleteContact(id, rev) { return new Promise(resolve => { let contact = {_id: id, _rev: rev}; this.db.remove(contact).catch((err) => { console.log('deleting contact error: ', err); this.success = false; }); if (this.success) { resolve(true); } }); } } ```

DON'T forget to add your own details for the username, password and url. Once done, save the file, and observe as your contacts get saved in the cloud, as-well.

Happy coding :)