Reputation: 2451
I have two controllers that communicate with each other.
Controller 1:
$scope.$on("reloadUsers", function (event) {
$http.get("/users").success(function(data) {
$scope.users = data;
console.log($scope.users);
});
});
$http.get("/users").success(function(data) {
$scope.users = data;
});
Controller 2:
$scope.editUser = function(id){
$http({
url: "/users/"+ id,
method: "PUT",
data: {
"firstName":$scope.user.firstName,
"lastName": $scope.user.lastName,
}
});
$scope.$emit("reloadUsers");
}
My templates are as shown below (both modal dialogs):
Template 1:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" ng-controller="Controller 1">
<div ng-repeat="user in users>
<a data-toggle="modal" data-target="#configureUserModal" href="#" ng-click="getUserId(user.id)" data-id="user.id">{{user.first_name + ' ' +user.last_name}}</a>
</div>
</div>
Template 2:
<div ng-controller="Controller2" class="modal fade" id="configureUserModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<label for="">First Name:</label>
<input type="text" value="{{userData.first_name}}" ng-model="user.first_name" />
<label for="">Last Name:</label>
<input type="text" value="{{userData.last_name}}" ng-model="user.last_name" />
<button type="button" class="btn btn-default" ng-click="editUser(userData.id)" data-dismiss="modal">Save</button>
</div>
Essentially Template 1
has a list of users that I get from Controller 1's
scope. On clicking a user in Template 1
, I go to Template 2
which displays the user and has an option to edit (change first name and last name). Once I hit Save
, I make a HTTP PUT request, save the data, close the modal windows and call emit
.
The problem is: When I open Template 1
after this, I see the old first name and last name (not the updated ones). But when I click on the user to open Template 2
, the updated names are shown. How do I ensure the data is updated in Template 1
? Isn't angular supposed to update it when it sees a change in the $scope
variable?
Upvotes: 1
Views: 419
Reputation: 9094
I would try rewriting the following code:
$scope.editUser = function(id){
$http.put("/users/" + id,
{
firstName: $scope.user.firstName,
lastName: $scope.user.lastName
})
.success(function(){
$scope.$emit("reloadUsers");
});
}
Hope it works!
EDIT:
Custom update method.
angular.module('unknown', ['ngResource'])
.factory('Users', ['$resource', function($resource){
return $resource('/users/:id', { id:'@id' }, {
update: { method: 'PUT' },
get: { method: 'GET' }
});
}]);
Upvotes: 0
Reputation: 2451
I finally figured it out after a good deal of refactoring. First, I implemented a service to get my list of users.
angular.module('app').factory('usersService', function($http) {
var usersService = {
getUsers: function () {
return $http.get("/users/").then(function (response) {
return response.data;
});
}
};
return usersService;
});
I used then
because the HTTP GET request is asynchronous, but I can't display my list of users until the response data is received.
Then in Controller 1
, I added in these bits of code:
$scope.users = usersService;
usersService.getUsers().then(function (asyncUsers) {
$scope.users = asyncUsers;
});
$scope.$watch('users', function (users) {
if (angular.isDefined(users)) {
console.log("$scope.users has data");
}
});
$scope.$on("reloadUsers", function (event) {
usersService.getUsers().then(function (asyncUsers) {
$scope.users = asyncUsers;
});
});
In here, I basically just call the service and wait for $scope.users
to gets it value. To find out exactly when that happens, I just have a $scope.watch
function in there as well. I also have a function that waits for the reloadUsers
event emitted from Controller 2
which refreshes the data in $scope.users
.
And finally, in Controller 2
, I have:
$scope.editUser = function(id){
$http({
url: "/user/"+ id,
method: "PUT",
data: {
"firstName": $scope.user.firstName,
"lastName": $scope.user.lastName,
}
}).success (function(data) {
$scope.$emit("reloadUsers");
});
}
Just calling $scope.emit
to indicate that it's time to refresh. So I'm pretty sure my problem was the lack of communication between controllers since I hadn't used a service, as well as the asynchronous GET requests. This solution resolves both!
Upvotes: 1