Why is my supervisor calling the same change twice?

I have an AngularJS 1.4 * application running locally (for now). This application is hosted by the Laravel 5.1 RESTFul API.

I need to make this application representing a package trip. The package consists of days, from 0 to N days. Every day there is a list of services, from 0 to N services. And the hotel.

My web server, from which my laravel application uses, provides me with a pre-configured package containing a list of days: each with a list of services and hotel information (still not used). In the answer, I have a list of properties for the package (at the moment it does not matter) and an array of days called days_info . This answer is placed in $scope.package , on my PackageController . PackageController also declares a directive called packageBlock , which consists of a list of days and some other data for the package.

 <div ng-repeat="day in package.days_info" class='row'> <div class='col-md-12'> <package-days-block></package-days-block> </div> </div> 

Inside the <package-days-block> directive, I have another option to iterate over the list of services within each day.

 <div class='container-fluid' ng-repeat='service in day.services' ng-controller="ServiceController"> <service-block></service-block> </div> 

What when the problem starts: to my absence, now I have $scope.service inside my ServiceController . So, I started changing it to my need inside the ServiceController via $scope.service .

$ scope.service has a service_id attribute. I put a listener / observer on it, so at any time $ scope.service.service_id changed, I ask for another service_table (contains information about services based on the service_id previously selected or changed by the user), and put it in $scope.service.table .

 // ServiceController $scope.reloadServicesTable = function(service_id, service_day, date, paxes){ MandatoryService.getServiceTable(service_id, service_day, date, paxes) .then( function(service_data) { $scope.service.table = service_data; }, ... ); 

reloadServicesTable is called for the observer for service_id changes.

 // ServiceController $scope.$watch( 'service.service_id', // Places the watcher to watch the changes on the service ID. function(new_service, old_service) { if( new_service === old_service ) return; $scope.reloadServicesTable($scope.service.service_id, $scope.service.service_day, $scope.day.date, $scope.package.paxes); } ); 

The problem begins here: a service table request is called twice when service_id is changed only once.

WHY GOD WHY ?!

There is another part of my code where I, from the PackageController, run through the entire days_info array and read the value of the price attribute inside service.table: service.table.price . There I understand that there are two areas : one that I process, and the other - I do not have a FREAKING IDEA , where it came from!

If I put console.log($scope); inside the method that goes through days_info, I get two areas for each request. This method is in the PackageController.

Any ideas why this is happening?

PS: This is my first AngularJS application, so it’s easy if I messed up something basic ...

EDIT:

As one of the participants noted in the comments, my question was not very reproducible. Unfortunately, I can’t put here only the part that I doubt because I have no idea where the problem is! (I know this doesn't help much)

I took some screenshots from the Chrome console:

Firstly, requests that are triggered when service_id changes

Service Change Request Log (sorted by path name)

As you can see, each request is called twice each time. This is not a one-time thing. /api/service/{id}... is a call for the service table information. /api/service/by_route/origin/... returns a list of services from one city to another (or the same). One does not interfere with the other.

Another image is the output of console.log from the PackageController $ area when the service_id parameter changes.

Areas for PackageController

As you can see, there are two different areas. And region b is the son of region r . Does r also call an observer on service_id ?

The sum price call is called twice from different places, as you can see in the image below:

Stack call for sumPrices method on PackageController

+8
angularjs angularjs-ng-repeat angularjs-scope
source share
2 answers

This may solve the problem. Even I came across exactly the same as you mention.

  • The reason for me was that the controller was initialized again, and a separate api call was written in it, which was intended for the initial loading of the page.

  • There may also be a scenario in which you assigned the controller twice in the label up.

+3
source share
 <div ng-repeat="day in package.days_info" class='row'> <div class='col-md-12'> <package-days-block day="day"></package-days-block> </div> </div> <div class='container-fluid' ng-repeat='service in day.services'> <service-block service="service"></service-block> </div> 

Pass day and service down into directives. Use two-way binding to pass the day and service changes back to package.days_info.

Remove your ServiceController . It doesn't make sense to ng-repeat the controller. <service-block> and <package-days-block> are E directives that handle logic.

Write only one observer in the PackageController that looks at package.days_info When your day or service changes change, it can just find out and do something.

Just cool and fix.

+1
source share

All Articles