Reputation: 11
I have a JSON object that looks like:
[
{
"empName": "John",
"ID": 1
},
{
"empName": "Sam",
"ID": 2
},
{
"empName": "Ben",
"ID": 3
}
]
In the view I want a dropdown where the user selects one of the names. I'm using ng-options
to achieve this:
<select ng-options="item as item.empName for item in employees track by item.ID" ng-model="emp.selected">
</select>
If I hard-code the JSON into the variable employees
in my controller the select renders. However if I use:
$.getJSON("path to JSON file",function(json){
$scope.employees = json;
});
The select is not populated. I've tried adding in $scope.$apply() to no avail. Any suggestions?
Update 1
Taking on board the answer from Iso I'm still left with the select not binding. For example If my javascript is:
app.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$scope.employees = [
{
"empName": "John",
"ID": 1
},
];
$http.get(" --PATH TO JSON-- ").then(function (res) {
$scope.employees = res.data;
console.log($scope.employees);
});
}]);
The select is still only populated with the first name 'John' despite the fact that the console.log
returns the full object with all three names.
Upvotes: 0
Views: 47
Reputation: 3238
You need to either call $scope.$evalAsync()
, or use $http
instead of jQuery here (which I would recommend):
$http.get("path to JSON file").then(function (res) {
$scope.employees = res.data;
});
The reason for this is that $http
is aware of AngularJS' digest cycle, whereas jQuery is not.
Refrain from using $scope.$apply()
(which can fail if a digest cycle is in progress), and $timeout
(which is heavy since it provokes a digest cycle of all your scopes).
Upvotes: 1
Reputation: 3967
You should use promises with the $q
library in Angular.
var getEmployees = function () {
var deferred = $q.defer();
$.getJSON("path to JSON file", function (json) {
deferred.resolve(json);
});
return deferred.promise;
}
getEmployees().then(res){
$scope.employees = res.data;
}
EDIT
If you use $timeout
is not really as correct a solution, as it doesn't give you control over the synchronicity. However, using $http
to make your calls comes with promises built in, I believe.
Upvotes: 0
Reputation: 25797
Wrap your code inside $timeout
:
$.getJSON("path to JSON file", function (json) {
$timeout(function () {
$scope.employees = json;
})
});
The call to $apply
may fail when the digest cycle is already in progress.
But consider using the $http
instead of using jQuery to pull data.
Upvotes: 0