Distinguishing between resolving a promise in a service/factory as opposed to in a controller within AngularJS

After experimenting with resolving a promise in both a service and a controller, I have found that I prefer to resolve it in the service so that I can reuse the variable without having to resolve it multiple times. However, I am encountering an issue where the data is being returned very slowly, taking about 5 or 6 seconds for my ng-options to populate. This makes me wonder if I am approaching this incorrectly. Which method is better? And how can I optimize my code to improve its speed?

Promise Resolved In Service:

resortModule.factory('locaService',['$http', '$rootScope', function ($http, $rootScope){
    locaService.getLocations=
        function() {
            return $http.get('/api/destinations').then(
                function(result){
                    locaService.locations= result.data;
                    return locaService.locations;
                }
            );
        return locaService.locations;
    };
resortModule.controller('queryController',['$scope', 'locaService', function($scope, locaService) {
    $scope.getLocations= locaService.getLocations().then(function(result){
       $scope.locations= result;
    });
}]);

Promise Resolved in Controller:

resortModule.factory('locaService',['$http', '$rootScope', function ($http, $rootScope){
locaService.getLocations=
    function() {
        locaService.locations= $http.get('/api/destinations');
        //stores variable for later use
        return locaService.locations;
    };
}]);
resortModule.controller('queryController',['$scope', 'locaService',          
    function($scope, locaService) {
       locaService.getLocations()
       .then(
            function(locations) // $http returned a successful result
            {$scope.locations = locations;} //set locations to returned data
       ,function(err){console.log(err)});
}]);

HTML:

<select ng-click="selectCheck(); hideStyle={display:'none'}" name="destination" ng-style="validStyle" ng-change="getResorts(userLocation); redirect(userLocation)" class="g-input" id="location" ng-model="userLocation">
    <option value=''>Select Location</option> 
    <option value='/destinations'>All</option>
    <option value="{{loca.id}}" ng-repeat="loca in locations | orderBy: 'name'">{{loca.name}}</option>
</select>

Answer №1

One of the advantages of using Angular is that services act as singletons, meaning there is only one instance in your app. This allows you to resolve data once (in your service), store it, and then simply return the already resolved data on subsequent calls. By doing this, you can avoid resolving your data multiple times and maintain a clear separation of logic between the service and controller.

UPDATE - It's recommended to cache promises instead, thanks yvesmancera for finding the bug.

resortModule.factory('locaService', ['$http', '$rootScope', function ($http, $rootScope) {
    var locationsPromise = null;

    locaService.getLocations =
        function() {
            if (locationsPromise == null) {
                locationsPromise = $http.get('/api/destinations').then(
                  function(result) {
                      return result.data;
                  }
                );
            }

            return locationsPromise;
        };

    ...
}

resortModule.controller('queryController',['$scope', 'locaService', function($scope, locaService) {
    $scope.getLocations= locaService.getLocations().then(function(result) {
        $scope.locations= result;
    });
}]);

If you're looking to speed up the loading of data, your JavaScript code seems fine. The slowdown could be caused by the API call itself. If you provide your HTML code, we can review it to see if there's anything that might be impacting performance.

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

Why do identical elements show different scrollHeights when overflowed and how can this discrepancy be resolved?

I am using a plugin that generates a <p> element and continuously fills it with the content from a <textarea>. This plugin positions the <p> directly below the <textarea>, and styles them so that they appear identical in terms of th ...

The Backbone model destruction URL fails to include the model's ID when trying to delete

I'm facing an issue in my app where I need to delete a model from a collection using "this.model.destroy" in my view, but it triggers a 405 response and the response URL doesn't include the model's id. According to the Backbone documentation ...

Transforming JSON output into a string without any prior understanding

My AJAX function generates a JSON output which also includes unnecessary XML due to an error in the JSON WebService. To remove this XML, I have utilized JavaScript Regular Expressions. AJAX Function function setJsonSer() { var strWsUrl = 'https: ...

Leveraging the reduce method in processing JSON data

Here is the JSON data I have: { "meta": { "totalPages": 13 }, "data": [{ "type": "articles", "id": "3", "attributes": { "title": "AAAAA", "body": "BBBB", "created": "2011-06-2 ...

Having trouble accessing an element after parsing JSON using jQuery, ending up with an "

Here is a snippet of code with a text and a button: <div id="divtest"> <h1> Bla </h1> </div> <button id="dugme1"> dugme </button> When the user clicks the button, the following script will be executed: $("#dugme1").cl ...

Setting up a Web application testing environment on its own

Embarking on my journey in web application development and testing, I am currently involved in a project that requires me to create a standalone environment for testing the web application. The main goal is to ensure the web application is easily testable ...

Is it better to throw an exception before doing any filtering?

Checking for the existence of removeId in the items before filtering to avoid exceptions. Is there a more efficient way to handle this without using two loops? This code may not be optimized due to the double looping process. const items = ...

Node.js/Firebase function to delete an item from a JSON object and update the existing items

I'm currently facing a challenge with updating a JSON file in Firebase after deleting an item using the .delete() function. Here is the original JSON data before deletion: "data": [ { "position": "3", ...

Is there a way to automatically change the display of an element once the user has closed the menu?

How can I ensure that the display of an element remains unchanged when a user opens and closes my website menu using JavaScript? ...

Generating varying commitments from one function

I have encountered an issue where I am returning a promise from a function that is part of a $q.all array. Initially, this setup works perfectly on page load. However, the challenge arises when I need to call this function multiple times afterward to updat ...

Validator alert for AMP scripts

I have implemented the amp version for my content management system. Since each article has a different body, some include amp-instagram while others include amp-facebook, and so on. In order to cover all bases, I have added both amp-facebook and amp-inst ...

The struggle of encoding: Making a JSON ajax call (utf-8) to convert Latin1 characters to uppercase

I've encountered a particular issue: the Javascript library I am developing utilizes JSON cross-domain requests to fetch data from a backend powered by Ruby on Rails: function getData() { $.ajaxSetup({ 'beforeSend': function(xhr) {xhr.s ...

Retrieve the array from the response instead of the object

I need to retrieve specific items from my database and then display them in a table. Below is the SQL query I am using: public async getAliasesListByDomain(req: Request, res: Response): Promise<void> { const { domain } = req.params; const a ...

Utilizing a Mocking/Spying Tool in Angular Unit Testing

I have a file named myHelpers.ts which contains multiple functions: myHelpers.ts export function multiply(a, b) { return a * b; } export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } The above file al ...

JQuery is having trouble with playing multiple sound files or causing delays with events

I've been working on a project that involves playing sounds for each letter in a list of text. However, I'm encountering an issue where only the last sound file is played instead of looping through every element. I've attempted to delay the ...

Ajax request not populating controller with data in ASP.NET CORE MVC

`Hello everyone, I'm running into a problem with my colleague's assignment and could really use some assistance. The issue pertains to ASP.NET Core MVC. I have an API Controller for editing student groups. This API Controller receives a GroupView ...

"Patience is key when it comes to waiting for an HTTP response

Looking for a solution in AngularJS, I have a service that calls the backend to get some data. Here is how the service looks: app.factory('myService', ['$http', '$window', '$rootScope', function ($http, $window, $ro ...

Store the JSON reply as a fixed variable

Recently, I have been delving into ReactJS and I've encountered a challenge of saving a JSON array as a 'const'. I have attempted the following approach: fetch(url) .then(response => response.json()) .then(json => { this.setSt ...

The JQuery mobile navigation menu effortlessly appears on your screen

I am experiencing an issue with a JQuery mobile navigation that is designed for screens @979 pixels wide. The problem arises when the screen is resized to 979px - the menu pops up fully extended and covers the content of the web page. I suspect that this ...

Learn how to retrieve data from the console and display it in HTML using Angular 4

Need help fetching data inside Angular4 HTML from ts variable. Currently only able to retrieve 2 data points outside the loop. Can anyone assist with pulling data inside Angular4? HTML: <tr *ngFor="let accept of accepts"> ...