I have an AngularJS 1.4* application running locally (yet). This app is served by an Laravel 5.1 backend RESTFul API.
I have to make this app that represents a package trip. A package is composed by days, ranging from 0 to N days. Each day have a list of services, ranging from 0 to N services. And a hotel.
My web server, from which my laravel application consumes from, delivers me a pre-setted package, containing a list of days: each one with a list of services and a hotel data (unused so far). On the response I have a list of properties for the package (that don't matter for now) and an array of days, called days_info
. That response is being put in the $scope.package
, on my PackageController
. The PackageController also declares an directive called packageBlock
, that consists in 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 <package-days-block>
directive, I have another to iterate through the list of services inside every day.
<div class='container-fluid' ng-repeat='service in day.services' ng-controller="ServiceController">
<service-block></service-block>
</div>
That's where the problem begins: to my undestandment, I now have a $scope.service
inside my ServiceController
. So, I started to change it on my need inside the ServiceController
through a $scope.service
.
The $scope.service has an attribute called service_id
. I put a listener/watcher on it, so at any time the $scope.service.service_id is changed, I ask for another service_table
(holds the informations about the services, it's based on the service_id previously choosen or changed by the user), and put it in the $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;
},
...
);
The reloadServicesTable
is called on the watcher for the service_id changes.
// ServiceController
$scope.$watch(
'service.service_id', // Places the watcher to watch the changes on the service's 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 starts here: the request for the service's table is called twice when the service_id only changes once.
WHY, GOD, WHY?!
There's another part of my code where I, from the PackageController, run through the entire days_info
array and reads the value of an attribute price
inside the service.table: service.table.price
. In there, I realise that there's two scope's: the one I handling and the other that I have no FREAKING IDEA where it came from!
If I put an console.log($scope);
inside the method that runs through the days_info, I get two scopes for every request. This method is on the PackageController.
Any ideas why this is happening?
P.S.: It's my very first AngularJS application, so, take easy if I messed up on something basic...
EDIT:
As pointed out by an fellow on the comments, my question wasn't very reproducible. Sadly, I can't put here only the part I'm having doubts cause I don't have the slightest idea where the problem lies! (I know that this isn't much of help)
I took some screen shots from the Chrome Console:
First, the requestions fired on the change of the service_id
As you can see, every request is called twice everytime. This is not an one-time-thing. The /api/service/{id}...
is the call for the service's table information. The /api/service/by_route/origin/...
returns an list of services from one city to another (or the same). One does not interfere on the other.
The other image is the output from a console.log from the PackageController $scope, on the time that the service_id is being changed.
As you can see, there's two different scopes. And the b
scope is son of the r
scope. The r
scope is also calling the watcher on the service_id
?
The call for the sums price is been called twice from differente places, as you can see in the image below:
Pass
day
andservice
down into directives. Use two way binding to pass yourday
andservice
changes back up to package.days_info.Remove your
ServiceController
It does not make much sense to ng-repeat a controller.<service-block>
and<package-days-block>
are E directive that handle logic.Write only one watcher in your PackageController that watch
package.days_info
When yourday
orservice
change, it can simply find out and do something about it.Just Chill and fix it.
It may solve you issue. Even i had faced exactly the same as you are mentioning.
The reason for me was that, the controller was getting initialized again and there was a separate api call written in that, which was intended to load the page initially.
There can also be a scenario where you have assigned controller twice in the mark up.