When using AngularJS to poll a $resource at regular intervals, the promise that is returned from the $resource call does not automatically get resolved

Let's get to the important details: When I link a $scope variable in my controller directly to a $resource, Angular takes care of promise resolution automatically and updates my view as soon as data is received from the service. However, I need to periodically check for updates from the server. Trying to bind to the promise returned by the $interval function does not trigger Angular's automatic promise resolution, and I'm unsure of how to make $interval work with a $resource.

My setup involves an Angular client, ASP.NET WebApi serving JSON, and Angular $resource interfacing with WebApi. When I connect a $scoped variable to my $resource promises within the Angular controller, it works fine; however, I face challenges when attempting to update these resources at intervals using $interval.

The code snippet that works but requires manual refreshing (relevant excerpt):

'use strict';
var ctrls = angular.module('MyModule',[]);
ctrls.controller('FooCtrl', ['$scope', '$location','service',
  function( $scope,$location,service)
  {
     $scope.Bars = service.Bars;
     $scope.Baz = service.Baz;
  }

var app = angular.module('MyModule.Services',['ngResource']);
app.service('service', ['$resource', function($resource)
{
  var proxy = $resource(
       'http://server/subsystem/api/Foo/:component',
        {},
        {
           Bars: {method:'GET',isArray:false,url: 'http://server/subsystem/api/Foo/Bars'},
          Baz: {method:'GET',isArray:false,rul: 'http://server/subsystem/api/Foo/Baz'}
        }
  return proxy;
}]);

blah blah blah, using ng-repeat in my view bound to "bar in Bars" displays data on screen.

Now, when I try to implement the interval in my controller, the promise doesn't resolve correctly.

Changes inside the controller (added $interval and $document to dependencies list):

var stop;
$scope.Bars = {};
$scope.Baz = service.Baz; //Angular resolves this promise automatically.
$scope.pollService = function(){
   if(angular.isDefined(stop))return;
   stop = $interval(function(){
     if(service){
        $scope.Bars = service.Bars;
     }
   },1000);
};
$scope.stopPolling = function(){
   if(angular.isDefined(stop)){
     $interval.cancel(stop);
     stop = undefined;
   }
};
$scope.$on('$destroy',function(){
   $scope.stopPolling();
});
$document.ready(function(){
   $scope.pollService(); 
});

Edit

The issue I'm facing is that binding $scope.Bars directly to service.Bars triggers Angular's automatic promise resolution, but adding the $interval call seems to be problematic. Checking $scope.Bars in Chrome Dev Tools shows that it remains an unresolved promise.

I have updated my sample code to reflect what I'm currently debugging. There are several properties defined on my resource, including one named 'Baz'. If I assign $scope.Baz = service.Baz directly in my controller, the view binds to it once Angular resolves the promise, whereas the one triggered by the interval does not.

Answer №1

It seems like there is an issue with the way you are handling promises in your $scope.pollService. Make sure to return the promise by adding return stop; at the end of your function. In addition, be cautious about the timing of your API calls as it may result in returning undefined if stop is defined.

To address this, consider revising your code snippet:

$scope.pollService = function(){
   if(!angular.isDefined(stop)) {
       stop = $interval(function() {
         if(service){
            $scope.Bars = service.Bars;
         }
       }, 1000);
  }

  return stop;
};

Furthermore, using a more descriptive variable name than stop would enhance clarity in your code structure.

UPDATE:

Based on my interpretation of the documentation, try invoking the action method on the service like $scope.Bars = service.Bars();. This approach will provide an object that will dynamically populate data once the promise resolves. However, exercise caution regarding timing issues between interval firing and promise resolution - utilizing $timeout might offer better results.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Filling in a text field with the text content (rather than the value) from a dropdown menu

Presently, I have the select box with the id "title" populating a text field with the id "costcenter". The current code works perfectly fine when using the VALUE of the select box to trigger the population of the cost center field. However, my requirement ...

Why am I unable to access the array once the loop has finished?

While utilizing the Google Maps API and AngularJS (1.5.8), I encountered an issue where I couldn't access markers that were created in a loop. The code snippet below is located inside the initMap function: var markers = []; for(var i=0; i<10; i++ ...

How to target only the parent div that was clicked using jQuery, excluding any

I have attempted to solve this issue multiple times, trying everything I could find on Google and stack overflow without success. At times I am getting the span element and other times the div - what could be causing this inconsistency? $(".bind-key"). ...

Display a specific number of page indicators on the Flickity plugin

Currently, I am utilizing the flickity plugin to create a slideshow feature on my website. My goal is to display navigation dots on the images to facilitate user interaction. If you are interested, you can access the plugin through this link: I would lik ...

What separates the functions `useRef` and `createRef` from each other?

As I was delving into the hooks documentation, I came across useRef. Upon examining their example… function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` refers to the mounted text inpu ...

What causes the _.sum() function in lodash to not work with objects in Vuejs?

I've encountered an issue where using Vuejs and Lodash in conjunction with a computed property that calculates the sum of a property in a collection results in unexpected behavior. Instead of summing the values, it seems to concatenate the string [obj ...

Traversing a nested array using jQuery

I'm attempting to utilize jQuery's each function in order to iterate through the provided array. My aim is to identify the key ("Name") and display its corresponding array values on the webpage. Array ( [E-mail] => Array ( ...

Having trouble importing the UpgradeModule from @angularupgradestatic in Angular version 2.2.1

I am in the process of updating my AngularJS (ng1) application to Angular 2 (ng2). My Angular version is 2.2.1. Upon importing UpgradeModule from @angular\upgrade\static, I encountered the following exceptions: Uncaught SyntaxError: Unexpected ...

Is there a way to modify the font while typing on an SVG path?

I'm working on a code snippet that adds letters along a path to create a typing effect. However, I want the last part of the text "It's our jam" to be displayed in a different font compared to the rest, as shown in the image at the bottom. Is the ...

When making an Ajax post request, the loading indicator may not appear

I've implemented the jQuery code below for an autocomplete input field, but I'd like to have a spinner display while waiting for the response from the server. In my code, I'm using search: to show the loading div and open: to hide it. The s ...

Monitor modifications to a DOM element's ClientRect dimensions

I have developed a component that utilizes the context feature to register a DOM node and include it in a QuadTree. export default class SelectableGroup extends React.PureComponent { getChildContext() { return { register: this.register, ...

What is the best way to create an array containing dictionaries?

Hey there, I'm having an issue with my React.js code. Here's what I have: const array1 = [1, 4]; const map1 = array1.map(x =>{'x2': x * 2, 'x3': x * 3}); console.log(map1); // expected output: Array [{'x2': , 1, ...

Conceal the Ajax Div and display the Loader Div while waiting for the data to be

Trying to show a loader div until the Ajax-populated div is returned. Want to hide "responseDiv" until it's filled with Ajax data and display a loading div in the meantime. #loading { background: url('images/loading.gif') no-repeat cent ...

Accessing information from a JSON array

I am encountering difficulties in fetching data from a JSON file. Whenever I click the button, it triggers the call function which then retrieves data from the json.jsp file containing an array. However, I am unable to retrieve the data successfully. Below ...

Transform the characters within a string into corresponding numerical values, calculate the total sum, and finally display both the sum and the original string

I'm looking to convert a string containing a name into numerical values for each character, ultimately finding the sum of all characters' numerical values. Currently, only the first character's value is being summed using .charAt(). To achie ...

Login System Encounters Syntax Error Due to JSON Input Ending Abruptly

I'm currently working on implementing a login system, but I've run into an issue with unexpected end of JSON input. It's a bit confusing since the code works fine on another page. The error specifically points to line 12 in my JavaScript. H ...

Tally each div individually and display the count within each div, instead of showing the total count across

I have come across various solutions that show the total number of certain special divs, such as: $('.someclass').length However, I am facing a different challenge. I want to sequentially count each div with a numerical sequence. For instance, ...

Does AngularJS ng-if function appropriately in every module?

I've been working on showing and hiding my drag and drop feature when a document is brought onto the screen using AngularJS. It initially worked, but now I'm facing issues in certain modules even though the code remains consistent across all modu ...

Troubleshooting Yeoman and Angular: Routing troubles persist

I recently started exploring with yeoman to develop angular applications. I am facing an issue while trying to create routes using yo:angular route. After running the command: yo:angular route foo yeoman generates the following files: app/scripts/contr ...

Passing selection from child to parent in ReactJS

When it comes to passing data from parent components to child components, using props is a common practice. But how can data be sent back up to the parent component? I'm working on a set of dropdown menus where users can make selections: DropdownMen ...