@Calendee

Cordova Contacts Plugin with Ionic Framework

A few days ago, Raymond Camden posted an article about using the pickContact feature in the updated Cordova contacts plugin. I dabbled with it but ran into some problems. Unfortunately, those problems were my own.

Today, I've finally gotten around to trying this out with a sample Ionic Framework app. I've put together a really simple sample that just allows you to pick contacts from your address book and then add them to the list. With this updated plugin and Ionic's ease of use, you'll be done in just a few minutes.

tl;dr https://github.com/calendee/ionicPickContact

The app starts with an empty list:

When you first try to access the contacts, iOS asks for the app to have permission to access the contacts list.
Then, you're presented with the standard iOS contacts picker. It's SO nice not to have to code this yourself. Your users won't have any trouble recognizing what to do here.
You can filter the list to find the contact you want. Again, the contact picker manages all this for you.
When you're done, each time you select a contact, it gets added to the list.

The HTML for this is very simple :

<ion-pane>  
    <ion-header-bar class="bar-stable">
        <button class="button" ng-click="pickContact()">Contacts</button>
        <h1 class="title">Pick Contacts</h1>
    </ion-header-bar>
    <ion-content>
        <div class="list">

            <a class="item item-thumbnail-left" ng-repeat="contact in data.selectedContacts">
                <img src="{{contact.photos[0].value}}" ng-if="contact.photos.length > 0">
                <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/87/Silver_-_replace_this_image_male.svg/200px-Silver_-_replace_this_image_male.svg.png" ng-if="contact.photos.length === 0">
                <h2>{{contact.displayName}}</h2>
                <p ng-if="contact.emails.length > 0">{{contact.emails[0].type}} : {{contact.emails[0].value}}</p>
                <p ng-if="contact.phones.length > 0">{{contact.phones[0].type}} : {{contact.phones[0].value}}</p>
            </a>

        </div>
        <p class="padding">Profiles courtesy of http://commons.wikimedia.org/wiki/File:Silver_-_replace_this_image_male.svg</p>
    </ion-content>
</ion-pane>  

In the header, is a button "Pick Contacts". This calls a method on the controller.

    .controller("AppCtrl", ['$scope', 'ContactsService', function($scope, ContactsService) {

        $scope.data = {
            selectedContacts : []
        };

        $scope.pickContact = function() {

            ContactsService.pickContact().then(
                function(contact) {
                    $scope.data.selectedContacts.push(contact);
                    console.log("Selected contacts=");
                    console.log($scope.data.selectedContacts);

                },
                function(failure) {
                    console.log("Bummer.  Failed to pick a contact");
                }
            );

        }


    }])

The controller uses a "ContactsService". The ContactsService interfaces with Cordova and formats the selected contact.

    .service("ContactsService", ['$q', function($q) {

        var formatContact = function(contact) {

            return {
                "displayName"   : contact.name.formatted || contact.name.givenName + " " + contact.name.familyName || "Mystery Person",
                "emails"        : contact.emails || [],
                "phones"        : contact.phoneNumbers || [],
                "photos"        : contact.photos || []
            };

        };

        var pickContact = function() {

            var deferred = $q.defer();

            if(navigator && navigator.contacts) {

                navigator.contacts.pickContact(function(contact){

                    deferred.resolve( formatContact(contact) );
                });

            } else {
                deferred.reject("Bummer.  No contacts in desktop browser");
            }

            return deferred.promise;
        };

        return {
            pickContact : pickContact
        };
    }])

Let me know if you have any suggestions to improve this. Feel free to fork my repo and submit pull requests.