Thanatos
Thanatos

Reputation: 292

Angular js html not updating

I wrote a simple graphql query that fetches an array of objects. The array is showing up when I do console.log(). However, the array does NOT update the html when the data is fetched. I need to click on the screen for it to update.

I am using the Angular JS stack along with graphql. It seems though that the issue is to do with angular js only and not the API call.

The following is the api call in the JS:

graphql("...").then(
    result => {
        $scope.data = result.data;
});

HTML:

<div>{{data.length}}</div>

Upvotes: 0

Views: 214

Answers (3)

georgeawg
georgeawg

Reputation: 48968

A cleaner approach is to convert the third-party promise to an AngularJS promise with $q.when:

$q.when(graphql("...")).then(
    result => {
        $scope.data = result.data;
});

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc...1 Since the promise comes from outside the AngularJS framework, the framework is unaware of changes to the model and does not update the DOM.

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

AngularJS $q Service API Reference - $q.when

Upvotes: 3

Shalom Peles
Shalom Peles

Reputation: 2632

Try to add scope.$apply();. Like this:

  graphql("...").then(
                    result => {
                        $scope.data = result.data;
                        $scope.$apply();
                    }); 

Upvotes: 1

Nidhin Joseph
Nidhin Joseph

Reputation: 10237

A better approach over $apply is $timeout.

The $timeout does not generate error like "$digest already in progress" because $timeout tells Angular that after the current cycle, there is a timeout waiting and this way it ensures that there will not any collisions between digest cycles and thus output of $timeout will execute on a new $digest cycle.

graphql("...").then(
  result => {
    $timeout(function() {
      $scope.data = result.data;
    });
  });

Upvotes: 0

Related Questions