Angular services are equipped with a powerful tool called the $http

Encountering an issue with promises within an angular service. The problem lies with a specific method getArea in the service which aims to retrieve the name of a service area. This data is obtained from the API. However, upon obtaining the service areas and trying to fetch the requested area's name, the code falls into an infinite loop. It seems there might be a misunderstanding regarding the usage of promises?

SupplierService:

var servicePromise;
var getServices = function(){
    if( !servicePromise ){
        servicePromise = $http.get('/api/services')
            .then(function(res){
                return res.data.data;
            });
    }
    return servicePromise;
};


var myService = {

    getServices : getServices,

    getArea : function(questionnaireId){
        getServices().then(function(services){
            // ...
            return "hello world";
        });
    }
};

return myService;

Controller:

$scope.supplierService = SupplierService;

View:

<div>
    <b>Area:</b> {{ supplierService.getArea(r.questionnaireId) }}
</div

The expected result in the view is "Area: hello world", but instead, it remains stuck in an infinite loop.


Update 1: A public function getServices has been added to the service, accessible from the controller like this:

SupplierService.getServices().then(function(d){
    $scope.services = d;
});

Hence, the issue likely resides within the getArea method?


Update 2: Took inspiration from this response . Intending to cache the outcome.


Update 3: Sharing a plunker. Trying to access supplierService.getArea(100) from the view renders the browser unresponsive.

Answer №1

If you want your service to be more efficient, consider structuring it like this:

var getServices = function(){
    var deferred = $q.deferred();
    $http.get('/api/services')
            .then(function(res){
                deferred.resolve(res.data)
            });
    return deferred.promise;
};

Make sure to return the deferred.promise when creating a deferred object. Then, upon the completion of the asynchronous call, use deferred.resolve or deferred.rejected accordingly to trigger success or error functions.

I have also created a plunkr that demonstrates different ways to fetch data from a service into Angular controllers, as this is a common challenge for developers new to Angular.

http://plnkr.co/edit/ABQsAxz1bNi34ehmPRsF?p=info

While not the absolute best practices, the plunkr showcases three methods of "sharing" data. Keep in mind that these methods rely on angular.copy, so the property storing the data on the service must be an Object or Array (primitive types won't work).

Below is a revised version of the function inline:

var myService = {
    var dataLoaded = false;
    var data = {}; //or = [];
    getServices : function(){
        var deferred = $q.defer();
        if( !dataLoaded ){
            $http.get('/api/services').then(function(res){
                angular.copy(res.data, myService.data);
                deferred.resolve(myService.data);
            }, function(err){
                deferred.reject("Something bad happened in the request");
            });
        }
        else
        {
            deferred.resolve(myService.data);
        }
        return deferred.promise;
    }
};

return myService;

In this revision, a new promise is created using the $q service (which needs to be injected). This approach allows for resolving the promise with existing data or fetching new data from the service. It's designed to handle async operations effectively. If multiple data sets need loading, an object can be used instead of a single boolean to store flags.

Answer №2

I believe that if you utilize the $http callback properly, it can greatly enhance your code structure.

//$http.get('/someUrl').success(successCallback);


var fetchServices = function(){
    return $http.get('/api/services');

};

fetchServices.success(function(services){
// ...
           return "greetings Earthlings";
        });
   }

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

Utilize Angular to implement tickbox filtering on a JSON file

Is there a way to filter JSON results based on both ladies and mens 'styles' without needing three tick boxes? Some products have dual gender styles, so how can we display results for 'both' without duplication? Your help is much apprec ...

The copyFileSync function is failing to copy the file without generating any error messages

I have developed a JavaScript function running in a nodejs/Electron client to copy a file from the user's flash drive to c:/Windows/System32. The file is copied to enable manual execution from Command Prompt without changing directories. The issue I ...

The state of a button being loaded and the ng-disabled attribute

Is there a solution for the ng-disabled not functioning properly when using $().button('loading') & .button('reset')? Any suggestions on how to resolve this issue? Feel free to take a look at my Plunker. ...

Issue: Catching errors in proxy function calls

I am currently using Vue 3 along with the latest Quasar Framework. To simplify my API calls, I created an Api class as a wrapper for Axios with various methods such as get, post, etc. Now, I need to intercept these method calls. In order to achieve this ...

Update header component dynamically upon successful login with Angular 11

I am currently using Angular 11 and facing an issue with displaying the username in the header component. The header loads before the login component, which results in the user data being stored in local storage only after the login component is loaded. As ...

Refresh all the data points displayed on the c3.js chart

I created a basic div element in my HTML code: <div class='all'> Show all </div> Accompanying that, here is the JavaScript code I implemented: $(document).ready(function () { $('.all').click(function(){ ch ...

Error: The cordovaLocalNotification plugin is attempting to read a property 'plugins' that is undefined, resulting in a TypeError

I am currently working on a hybrid application using the Ionic platform. I am trying to integrate Cordova local notification features, but I keep getting an error message saying "cannot read property 'plugins' of undefined." Below is my code. Can ...

How to implement flash messages in Node.js forms submission process

Recently, I've been attempting to implement a Bootstrap style alert that appears after submitting a contact form using Node JS/Express. My view is based on an ejs template. mailerRoutes.js const nodemailer = require('nodemailer'); const ma ...

The most basic security measure for safeguarding a webpage

Currently, I am developing a website that requires customers to input a specific "code" in order to gain access. Upon visiting the site, users will be prompted to enter a simple code to proceed further. My programming skills are limited to HTML, CSS, and J ...

When transmitting JSON data from the View to the Controller in ASP.NET MVC, the received values are

I'm facing an issue with sending JSON data from an MVC View to Controller. All I seem to get in the Controller is: https://i.sstatic.net/4pKNF.png The JSON I send in Url.Action looks like this: (I create it myself by adding arrays together using .pu ...

Is it achievable to refresh ng-repeats in Angular.js using the current scope data?

I currently have a series of interconnected ul lists in my view that are utilizing jQuery UI: Sortable to allow for drag and drop functionality for reordering items within the list. After making changes via jQuery UI's drag and drop, I update the $sc ...

BiQuadFilters vs. Personalized Filter - Harnessing the Power of the Javascript WebAudio API

As part of my downsampling process from 48kHz to 16kHz, I need a filter to prevent aliasing. Thankfully, the WebAudio API provides built-in filters that I can utilize: biquadFilter = context.createBiquadFilter(); biquadFilter.type = "lowpass"; biquadFilte ...

Is it possible to improve the cleanliness of a dynamic button in Jquery?

I've just finished creating a dynamic button on the screen as per my boss's request. When this button is clicked, it triggers an email window for feedback submission. My aim is to streamline this script so that I can avoid digging into ASP marku ...

What mistake am I making with arrays?

My understanding of JavaScript and Node.JS is still developing, so I'm puzzled as to why I'm receiving NaN when using this expression: var aUsersBetted = {}; aUsersBetted['1337'] += 200000; logger.debug(aUsersBetted['1337']); ...

The 'file' property of undefined throws an error in ng-file-upload

I am currently exploring the functionality of ng-file-upload from this repository: https://github.com/danialfarid/ng-file-upload I have successfully implemented the basic setup as follows: HTML: <section ng-controller="MyController"> ...

Displaying content while the page is reloading

I am currently using bootstrap tabs to display reports images that are dynamically generated by the SSRS Server. These images are saved in a local server folder and updated periodically in the background. However, whenever a user refreshes the page, the re ...

The Ladda spin animation continues spinning for an additional second after the stop() function is called

I employ the ladda spinner in this manner: var l = Ladda.create(document.getElementById('ladda-test')); l.start(); l.stop(); console.log('ladda is stoped'); The issue I am facing is that following the execution of l.stop(), the animat ...

Cross-origin requests cannot be resolved by Cors

I have been attempting to create an Angular app with ASP.NET MVC Web API. Whenever I send a $resource request to my local web server (localhost), I encounter the following error: XMLHttpRequest cannot load http://localhost:59636/api/studios. No 'A ...

Error: The 'filename' property of undefined cannot be read when attempting to upload a user profile photo using multer

I am facing an issue while attempting to upload a user profile photo using express.js server and Multer. I keep receiving the error message "TypeError: Cannot read property 'filename' of undefined." Below is the code snippets for both the server- ...

Problem with APIGEE search function

Encountered an issue while trying to retrieve an Apigee collection using the following code snippet: var my_pc_list = new Apigee.Collection( { "client":client, "type":"pc_pedidos", qs :{ql:"limit:50"} }); Error details: {"error":"query_parse","timestamp ...