0

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>

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this answer. In my case, ui was updating when the network is fast, but it wasn't updating when network is slow. This solved my issue.
1

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

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

Comments

0

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;
    });
  });

1 Comment

Until you don't have a tree/cascade of 10 sub directives to update this is overkill. $apply is clearly sufficient

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.