3

I am writing a small AngularJS/Ionic/Cordova application where I have a list of contacts. When the user taps on a contact, I navigate to a new page where details about the contact are shown (first name, last name, phone number). Here, the user can update details about the contact, or delete the contact. The problem I have is when the user deletes the contact the list still shows the deleted item after navigating back.

Right now I am storing the list of contacts in localStorage, but I do plan on eventually persisting these values in SQLite and/or a web service.

I am using two controllers, two html templates, and a factory. Why is the first list not updating when I make changes to a detail item? I am very new to AngularJS so please bear with me.

List Controller

angular
.module('app')
.controller('contactListCtrl', ['$scope', 'Contacts',
    function($scope, Contacts) {

        $scope.contacts = Contacts.get();

    }
])

List Template

<ion-content scroll="false" class="padding-horizontal" has-header="true">
    <div class="row padding-vertical">
        <div class="col col-center text-center">
            <span class="small-text primary-text-color">Contact List</span>
        </div>
    </div>

    <div class="row" >
        <div class="col col-center">
            <ul class="list">
                <li class="item" ng-repeat="contact in contacts" ui-sref="contactListEdit({id: $index})">
                    {{contact.fName}} {{contact.lName}}
                </li>
            </ul>
        </div>
    </div>
</ion-content>

Detail Controller

angular
    .module('app')
    .controller('editContactCtrl', ['$scope', '$stateParams', 'Contacts',
    function($scope, $stateParams, Contacts) {
        var contactId = false;

        if ($stateParams.id !== 'undefined') {
            contactId = $stateParams.id;
        }

        $scope.contact = Contacts.get(contactId);
        $scope.contactId = contactId;

        $scope.delete = function(index) {
            Contacts.removeContact(index);
            window.history.back();
        };
    }
])

Detail Template

<ion-content scroll="false" class="padding-horizontal" has-header="true">
    <div class="row padding-vertical">
        <div class="col col-center text-center">
            <span class="medium-text primary-text-color">Edit contact</span>
        </div>
    </div>

    <div class="list">
    <label class="item item-input">
        <input type="text" placeholder="First Name" ng-model="contact.fName">
    </label>
    <label class="item item-input">
        <input type="text" placeholder="Last Name" ng-model="contact.lName">
    </label>
    <label class="item item-input">
        <input type="text" placeholder="Phone" ng-model="contact.mobile">
    </label>
    <label class="item item-input">
        <input type="text" placeholder="Email" ng-model="contact.email">
    </label>
    <button ng-click="save()" class="button button-full button-positive">
        Save
    </button>
    <button ng-click="delete(contactId)" class="button button-full button-assertive">
        Delete
    </button>
    </div>
</ion-content>

Contacts Factory

angular
    .module('app')
    .factory('Contacts', ['$http',
        function($http) {
            return {
                get: function(index) {
                    var contacts;
                    try {
                        contacts = JSON.parse(window.localStorage.getItem("contacts"));
                        if (index >= 0) {
                            return contacts[index];
                        }
                        return contacts;
                    } catch (e) {
                        console.log("error parsing json contacts");
                        return false;
                    }
                },

                removeContact: function (index) {

                    var contactList = this.get();
                    if (index !== -1) {
                        contactList.splice(index, 1);
                    }
                    console.log(contactList);
                    this.saveContacts(contactList);
                },

                setDefaultContacts: function() {
                    var self = this;
                    return $http.get('./mock_data/contacts.json').then(function(response) {
                        // contacts already exist, don't set.
                        if (window.localStorage.getItem("contacts")) {
                            return false;
                        } else {
                            self.saveContacts(response.data);
                            return true;
                        }
                    });
                },
                saveContacts: function(contactList) {
                    window.localStorage.setItem("contacts", JSON.stringify(contactList));
                },
            };
        }
    ])
njtman
  • 2,080
  • 1
  • 18
  • 30

1 Answers1

2

I think you will find that the contactListCtrl is not being setup again when you navigate back to it (after a delete). I believe this is because Ionic caches views for you.

What you need to do is listen to $ionicView.beforeEnter event and load your contacts list into your ContactListCtrl scope whenever you receive this event.

So.. Try adding something like this to your controller:

$scope.$on('$ionicView.beforeEnter', function() {
        $scope.contacts = Contacts.get();
    }
);

Check out: http://ionicframework.com/blog/navigating-the-changes/

Dylan Watson
  • 2,103
  • 1
  • 17
  • 38
  • This answer was perfect, it solved my problem. Is there a way I can automatically detect the change on the contact list and re-render the list instead of manually refreshing? I need to eventually support windows phone so I am going to be ditching ionic, and this seems to be a very ionic specific answer. Thanks again! – njtman Feb 20 '15 at 01:30
  • 1
    Haha no worries. Thanks for the reformat, I was on my phone :P I would think you could just subscribe to Contact changes in your controller. Check out: http://stackoverflow.com/questions/12576798/how-to-watch-service-variables – Dylan Watson Feb 20 '15 at 02:03