Yagiz
Yagiz

Reputation: 1033

Angular Directive captures initial null value of ng-model

I am using a custom directive and trying to capture the $scope.model and if it has initial value in it, I want to process that data etc.

My initial code was:

if ($scope.model && $scope.model.length > 0) {
  var id = angular.isArray($scope.model) ? $scope.model.join(',')
    : $scope.model;

  if (id)
    initialJobs.push(
      $http.get(config.root.api + 'sectors?id=' + id)
    );
}

Because $scope.model is null this if statement doesnt get processed. (I've put a console.log and saw that $scope.model was null).

If I have a timeout of 1000 ms, I capture the real data of $scope.model.

PS: $scope.model data is gathered through a HTTP request in controller and because of the two-way binding, it is first sent to view as null and when the data is formed, model value changes.

Thank you for reading :)

PS: I know that one solution to solve this problem is to resolve the async request in router layer, and than pass it to controller, where there won't be any delay in two-way binding. But I think it is a bad practice for this piece of problem.

Upvotes: 0

Views: 418

Answers (2)

Almar
Almar

Reputation: 11

Looks like you are processing data in a directive. That is a bad idea in my opinion. You state that the problem can be solved by using 'resolve' in the router but you think it's bad practice. It will solve you're problem though and it's a much better solution than you have now. Alternatively you can do the XHR calls from your controller. On the promise.then of the first you can do the second call. In the 'then' callbacks of the promises, update your model. Base your view on your model, MVVM, problem solved.

Upvotes: 1

CKK
CKK

Reputation: 909

You can add watcher to that value.

$scope.$watch('model', function(model, oldModelValue) {
    var id = angular.isArray(model) ? model.join(',') : model;

    if (id)
        initialJobs.push($http.get(config.root.api + 'sectors?id=' + id));
});

You have to be careful though, watcher invokes callback every time $scope.model is changed, even if it is null or any other unexpected value.


As for another and better solution, you can set $http call's return value (which is a promise) where you set $scope.model to a value like say $scope.modelPromise and you can then that promise.

$scope.modelPromise = $http.get('some-url').then(function(response) {
    $scope.model = response.data;
});

// somewhere else
$scope.modelPromise.then(function(response) {
    // do stuff here
});

I would suggest using $resource service, if that is not an overkill.

Upvotes: 2

Related Questions