0

I tried to pass data between controller and I made a service to do that. But somehow when I tried to get the data, it doesn't work. I have no idea where my mistake is. Here is the code:

This is the AngularJS file:

    var app = angular.module('Application', []);    

    app.controller('NotificationListController', function($scope,$http, NotificationService, Data) {
        var notificationList = NotificationService.getNotificationList();
        notificationList.then(function(response){
            console.log(response);
            $scope.notificationData = response.data;
            return response;
        });
        $scope.setEditedNotification = function(notification){
            $scope.editedNotification = Data.setNotificationValue(notification);
        }
    });

app.controller('NotificationEditController', function($scope, Data, TemplateService){
    $scope.editedNotification=Data.getNotificationValue();
});

app.service('Data', function(){
    var NotificationData;
    return{
        getNotificationValue: function(){
            return NotificationData;
        },
        setNotificationValue: function(notificationData){
            NotificationData = notificationData;
        }
    }
});

This is my index.html

<tr ng-repeat="notification in notificationData">
            <td>{{notification.name}}</td>
            <td>{{notification.sender}}</td>
            <td>{{notification.subject}}</td>
            <td>{{notification.template.name}}</td>
            <td><a class="btn btn-default" href="editNotification.html" role="button" ng-click="setEditedNotification(notification)">Edit</a></td>
            <td><a class="btn btn-default" href="#" role="button" ng-click="deleteNotification(notification.id, $index)">Delete</a></td>
        </tr>

edit.html:

<div class="form-group col-md-offset-1">
            <label for="inputNotifName" class="col-sm-1 control-label">Name</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.name" type="text" class="form-control" id="inputNotifName" placeholder="Notification name">
            </div>
        </div><br><br>
        <div class="form-group col-md-offset-1">
            <label for="inputNotifSender" class="col-sm-1 control-label">Sender</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.sender" type="email" class="form-control" id="inputNotifSender" placeholder="Sender">
            </div>
        </div><br>
        <div class="form-group col-md-offset-1">
            <label for="inputNotifSubject" class="col-sm-1 control-label">Subject</label>
            <div class="col-md-6">
                <input ng-model="editedNotification.subject" type="text" class="form-control" id="inputNotifSubject" placeholder="Subject">
            </div>
        </div>

I debugged it and I found out that the value of $scope.editedNotification is not being updated when I called Dara.setNotificationValue(notification);. And also when I tried to get var NotificationData after I set it, the value still null. I guess there is something wrong at the way I call the service.

2
  • What are you expecting to happen with this $scope.editedNotification = Data.setNotificationValue(notification);? setNotificationValue() doesn't return anything so this is likely setting $scope.editedNotification to null. Without seeing how you've set ng-controller it's possible that the shared scope is causing this issue to propagate to the other controller. Commented Mar 17, 2016 at 18:25
  • yes, may be I am wrong because I assign it to $scope.editedNotification. By calling setNotificationValue(notification), I am expecting to set the value of var NotificationData. It suppose to be updated when I call set function. In this case, the value still null even after I called set method. Commented Mar 18, 2016 at 1:34

1 Answer 1

0

I am going to show you a simplified sample that will hopefully get you on the right track. I wouldn't normally write all this, but I know how frustrating it can be to trying to figure this all out on your own from tutorials and examples that aren't quite doing what you want. Please note that this is not production-worthy code - it's for illustrative purposes only.

First the parts of your code that contain issues:

notificationList.then(function(response){
    console.log(response);
    $scope.notificationData = response.data;
    return response; <-- get rid of this
});

You don't return anything from the success callback of a promise because you're not assigning anything. In the sample code I have faked this part because I don't have access to your API to retrieve data.

app.service('Data', function(){
    var NotificationData;
    return{
        getNotificationValue: function(){
            return NotificationData;
        },
        setNotificationValue: function(notificationData){
            NotificationData = notificationData;
        }
    }
});

Your service definition is actually a factory. When you use .service() you have to use this. to set the methods inside the service. To return functions as you have done you need to use .factory(). I used a factory in the sample code.

$scope.setEditedNotification = function(notification){
    $scope.editedNotification = Data.setNotificationValue(notification);
}

Here you are effectively setting $scope.editedNotification to null. In the sample code I used a factory with getter/setter methods for a selectedNotification object. I am also broadcasting a change because in the sample code everything is on one view. I highly recommend you use a routing solution because your use of navigation between pages is what is causing your null issue - this is the nature of a SPA.

Here's the sample code. First the JS:

var app = angular.module('Application', []);

app.controller('NotificationListController', function($scope, $http, Data, NotificationService) {
    /* below I'm faking up some data, this replaces the following code from your original post
     with corrections:
    var notificationList = NotificationService.getNotificationList();
    notificationList.then(function(response) {
        console.log(response);
        $scope.notificationData = response.data;
    }); */
    $scope.notificationData = NotificationService.getNotificationList();

    $scope.setEditedNotification = function(notification) {
        Data.notificationData = notification;
    };

    $scope.deleteNotification = function(notificationId) {
        // whatever you do to delete a notification
        Data.notificationData = {};
    };
});

app.controller('NotificationEditController', function($scope, Data) {
    // here I am responding to an event that is raised when setting the 
    // selected notification - you should handle this via routing within
    // your app
    $scope.$on('notificationSelected', function () {
        $scope.editedNotification = Data.notificationData;
    });
});

app.factory('Data', function($rootScope) {
    var _notificationData = {};
    var service = {
        get notificationData() {
            return _notificationData;
        },
        set notificationData(value) {
            _notificationData = value || {};
            $rootScope.$broadcast("notificationSelected");
        }
    }
    return service;
});

app.service('NotificationService', function() {
    this.getNotificationList = function() {
        return [{
            id: 1,
            name: "Notification 1",
            sender: "Sender 1",
            subject: "Subject 1",
            template: {
                name: "Template 1"
            }
        }, {
            id: 2,
            name: "Notification 2",
            sender: "Sender 2",
            subject: "Subject 2",
            template: {
                name: "Template 2"
            }
        }, {
            id: 3,
            name: "Notification 3",
            sender: "Sender 3",
            subject: "Subject 3",
            template: {
                name: "Template 3"
            }
        }];
    }
});

And the HTML:

<div ng-app="Application">
    <div ng-controller="NotificationListController">
        <table border="1">
            <tr ng-repeat="notification in notificationData">
                <td>{{notification.name}}</td>
                <td>{{notification.sender}}</td>
                <td>{{notification.subject}}</td>
                <td>{{notification.template.name}}</td>
                <td><a class="btn btn-default" href="editNotification.html" role="button" ng-click="setEditedNotification(notification); $event.preventDefault();">Edit</a></td>
                <td><a class="btn btn-default" href="#" role="button" ng-click="deleteNotification(notification.id, $index); $event.preventDefault();">Delete</a></td>
            </tr>
        </table>
    </div>
    <div ng-controller="NotificationEditController">
        Selecting a notification in the table above should cause it to be displayed here.
        <div>
            ID: {{editedNotification.id}}
            <br> Name: {{editedNotification.name}}
            <br> Sender: {{editedNotification.sender}}
            <br> Subject: {{editedNotification.subject}}
            <br> Template: {{editedNotification.template.name}}
        </div>
    </div>
</div>

And a JSFiddle for you to tinker around with. I hope this helps. There are likely ways to better structure this or refactor portions, but hopefully this should get you started.

Sign up to request clarification or add additional context in comments.

2 Comments

So I need to use routing to get the selected data? Do you have any good reference to learn about it? I have some references but it difficult to understand.
Routing is for navigation within your app. The service is how you pass data between controllers. You have several choices for routing, but I would recommend ui-router. There are abundant resources to learn about routing in general and ui-router specifically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.