1

I have service module which read JSON file and returns JSON data. Here is code

angular.module('serviceModule').service('dataService',["$http",function($http){
return {
    getData:function(file){
        return $http.get('url to json file').then(function(response) {

            return response.data;              
 });                        
    }

I am getting this data in my directive and assigning it to my $scope variable.

angular.module('xyz').directive('xyz',function(dataService){
  return {
   templateUrl:'hfhf',
   controller:'hgf',
   link:function($scope){
        console.log("Hi");

               $scope.tasks=[];
      dataService.getData('location to json file').then(function(data){
         $scope.tasks=data;
      });

so my main problem is I have another controller which is changing value at 'location to JSON value',but this change is not reflecting immediately when I refresh the web page then only those change are reflecting. I have tried implementing with watcher but it throws ERROR continuously and my browser becomes unresponsive. Can anyone please help me to reflect changes immediately when change happens in 'location to JSON value'

My HTML directive as asked by some of you .In directive, i am doing

<div ng-repeat='task in tasks track by $index' class="xyzwell"data-jqyoui-options="{revert: 'invalid'}" data-drag="true" jqyoui-draggable="{index: {{$index}},placeholder:'true', animate: true,onStop:'dragStopCall()'}" id='{{$index}}' >
<div class="editIcon " >

    <div class="pull-right">
<i class="fa fa-cog"></i>
    <i class="fa fa-trash" aria-hidden="true"></i>
</div>
    </div>
<div class="taskDetailarea">
    <p>{{$index}} {{dragStopCall}}</p>
<p>{{task.xy}}</p>
    <p>{{task.abc}}</p>
    <p>{{task.bcd}}</p>
</div>

Here I am using ngDragDrop thats why I have added those tags those are working fine.I am just iterating through tasks thats all.

ivan R
  • 296
  • 2
  • 16
  • Show your `html` template of directive. – Stepan Kasyanenko Sep 04 '16 at 05:44
  • @StepanKasyanenko sure if u required i will add this – ivan R Sep 04 '16 at 06:29
  • Can u please share th controller how it is changing the data? – RIYAJ KHAN Sep 04 '16 at 06:55
  • What kind of error happens, when you using `watcher`? – Stepan Kasyanenko Sep 04 '16 at 08:41
  • Watcher listening expressions need to be synchronous. They don't work with asynchronous services. Is the other controller which is posting data to the url using the `dataService` service? The directive needs to be notified by the service when changes are made to the url of interest. – georgeawg Sep 04 '16 at 10:50
  • @georgeawg yes, i am using dataService only to posting data to URL but from a different controller.I don't know how to notify when data change happens to URL and make use of this. – ivan R Sep 04 '16 at 15:32
  • @StepanKasyanenko I am using the same service to reflect changes from the different controller so I don't think it is necessary to post code for the different controller. – ivan R Sep 04 '16 at 15:35
  • 1
    I am not sure if I completely understand your issue, but take a look at $broadcast/$emit and $on. When your controller makes a change, publish a message with $broadcast or $emit, and then wire up your directive to listen for that event using $on. Here is a great SO link: http://stackoverflow.com/questions/14502006/working-with-scope-emit-and-on – Tim Hobbs Sep 04 '16 at 18:21
  • @TimHobbs Thanks with this great link i am able to figure out and now its working .Please post your suggestion as answer i will mark it accept – ivan R Sep 05 '16 at 08:54
  • @ivan - Glad it worked out for you. I posted my comment as an answer and added a little borrowed text from the original SO link to illustrate the usage. – Tim Hobbs Sep 06 '16 at 15:25

3 Answers3

2

As asked, I am posting my comment as an answer since it worked for the OP.

I am not sure if I completely understand your issue, but take a look at $broadcast/$emit and $on. When your controller makes a change, publish a message with $broadcast or $emit, and then wire up your directive to listen for that event using $on. Here is a great SO link: Working with $scope.$emit and $scope.$on

I'll borrow from the link to give an overview here as well:

$broadcast -- dispatches the event downwards to all child scopes

$emit -- dispatches the event upwards through the scope hierarchy.

So a quick example of the usage would be:

function firstCtrl($scope)
{
    $scope.$broadcast('someEvent', [1,2,3]);
}

function secondCtrl($scope)
{
    $scope.$on('someEvent', function(event, mass) { console.log(mass); });
}
Community
  • 1
  • 1
Tim Hobbs
  • 2,017
  • 17
  • 24
0

i am using dataService only to posting data to URL but from a different controller.I don't know how to notify when data change happens to URL and make use of this

There are several approaches to this problem. One is to keep a local copy in the service and use a watcher on the local copy.

app.service('dataService',function($http){
    var dataService = this;
    this.localCopy = {};
    this.getData = function(url){
        return $http.get(url).then(function(response) {
            dataService.localCopy[url] = response.data;                
            return response.data;              
        });                        
    };
    this.postData = function(url, data) {
        dataService.localCopy[url] = data;
        return $http.post(url,data).then(function (response) {
            return response.data;
        });
    };
});

The directive can put a watcher on the local copy of the data.

app.directive('xyz',function(dataService){
    return {
       templateUrl:'hfhf',
       controller:'hgf',
       link: function(scope){
            console.log("Hi");
            dataService.getData(url);
            scope.$watch(
                function() {return dataService.localCopy[url]},
                function (newValue) { scope.tasks = newValue;}
            );
       }
    }
});

By watching the local copy of the data in the service, the directive will see the changes created by other users of the service.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
-2

Try this:

dataService.getData('location to json file').then(function(data){
         $scope.tasks=data;
         $scope.$apply();
      });

This will force a digest cycle and update all your watchers making sure the changes in scope are reflected in your view.

This blog post explains more

Batman
  • 5,563
  • 18
  • 79
  • 155
  • I have tried this but its throwing ERROR for more info about ERROR https://docs.angularjs.org/error/$rootScope/inprog?p0=$digest – ivan R Sep 04 '16 at 04:40