Reputation: 507
I am writing an application that is running AngularJs & Bootstrap on the frontend - and using angularjs' $http to make calls to an API...I have two controllers within one app -- the first controller displays the person's name and the second controller displays a list of performances that this person has seen...
<html lang="en" ng-app="myapp">
...
<div class="panel-body" ng-controller="Ctrl">
<div class="row">
<div class="col-sm-3" style="height: 50px;">
<div class="well well-sm">
First Name:
<a href="#" editable-text="user.fname">{{ user.fname || "empty" }}</a>
</div>
</div>
<div class="col-sm-3" style="height: 50px;">
<div class="well well-sm">
Last Name:
<a href="#" editable-text="user.lname">{{ user.lname || "empty" }}</a>
</div>
</div>
</div>
</div>
<div class="list-group" ng-controller="Ctrl2">
<div ng-repeat="obj in performances" >
<div class="list-group-item">
<h4 class="list-group-item-heading">
<span class="badge">
{{$index+1}}</span> {{ obj["Perf_name"] || "empty" }}</h4>
<p class="list-group-item-text">
Date: {{ obj["Perf_dt"] || "empty" }}<br />
Theater: {{ obj["Theater"] || "empty" }}<br />
</p>
</div>
</div>
</div>
...
</html>
In the JS file I have the following code
Declare my variables and module
var app = angular.module("myapp", ["xeditable"]);
var q = getUrlParameter("q"); // get the query param
var baseurl = "https://some.domain/service/getCRM";
var baseurl2 = "https://some.domain/service/getPerformances";
Create a service to be used by both controllers
app.service('crmService', function () {
this.id = 0;
this.getID = function () { return this.id };
this.setID = function (newid) { this.id = newid; };
});
Define Controller #1
app.controller('Ctrl', function ($scope, $http, crmService) {
$http({
method: 'GET',
url: baseurl,
respondType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
params: {
phone_no: q
}
}).then(function successCallback(response) {
$scope.user = {
fname: response.data[0]["FirstName"],
lname: response.data[0]["LastName"]
}
crmService.setID(response.data[0]["CRM_ID"]);
console.log("*** OUTPUT LINE 1: " + crmService.getID());
}, function errorCallback(response) {
console.log("**ERROR");
console.log(response);
});
});
Define Controller #2
app.controller('Ctrl2', function ($scope, $http, crmService) {
console.log("*** OUTPUT LINE 2: " + crmService.getID());
var promise = $http.get(baseurl2 + "?crm_id=" + crmService.getID());
promise.then(
function (response) {
$scope.performances = response.data;
});
});
Console output
*** OUTPUT LINE 2: 0
*** OUTPUT LINE 1: 123456
Questions:
So I have to first controller working fine, but the second controller keeps thinking that the customer ID is 0 - when it should be 123456
What am I missing?
FYI: when I hard code an ID for the second controller to use, I get actual performance records back - so I know everything will work once I figure out how to share values between my controllers
Upvotes: 0
Views: 139
Reputation: 691625
Why is the second controller outputting before the first
Because the second controller logs the ID as soon as it's instanciated, whereas the first one logs it once it has received, asynchronously, a response to an HTTP request. The promise did work, since the output is logged in the console.
What I need to happen is, I make my GET call in the first controller block and assign the customer ID using my service...I then go on to the second controller block and using the customer ID, from my service
You're doing your job more complex than it should be: using a single controller would be much easier here, since the model of the second one depends on what the first one does.
You could broadcast an event from the first controller to signal that the ID has been set, and listen to the event in the second one to get the data at tis time.
app.controller('Ctrl', function ($scope, $http, $rootScope, crmService) {
$http({
...
}).then(function successCallback(response) {
...
crmService.setID(response.data[0]["CRM_ID"]);
console.log("*** OUTPUT LINE 1: " + crmService.getID());
$rootScope.$broadcast('crmIdChanged');
};
});
app.controller('Ctrl2', function ($scope, $http, crmService) {
function getPerformances() {
var id = crmService.getID();
if (id != 0) {
var promise = $http.get(baseurl2 + "?crm_id=" + crmService.getID());
promise.then(
function (response) {
$scope.performances = response.data;
});
}
}
getPerformances();
$scope.$on('crmIdChanged', getPerformances);
});
You could even broadcast the even from the service itself.
Upvotes: 1