Storing data retrieved from an asynchronous call in AngularJS to a variable

Here is the code where I am attempting to utilize promise to store data from an asynchronous call in a variable, but it's not functioning as expected. I am relatively new to promises and after some research, I learned that promises can be helpful in such scenarios. However, I am struggling to implement it correctly. Could you please point out where I might be going wrong in the following code snippet?

angular.module("app").controller("myCtrl", function($scope, $http, $q) {
    var deferred = $q.defer();

    var data = $http.get("/api/events").success(function(response){
    deferred.resolve(response);
    return deferred.promise;
    // I have also tried returning response directly;
    })
    console.log("DATA--");
    console.log(data);
});

EDIT -

I am trying to make two API calls -

1) Form an array of IDs from the first API call.

2) Iterate through the array to make a second API call based on each ID.

3) Combine certain data from array 1 and array 2.

The specific use case I am attempting is described further in the following link, where I am exploring the use of promises to achieve this -

http://pastebin.com/ZEuRtKYW

Answer №1

My approach to solving this would be as follows:

$http.get('data.json').success(function (result) {
    $scope.result = result;
}).then(function (data) {
    var result = data.data.key;

    var promises = result.map(function (val) {
        var deferred = $q.defer();

        $http({
            method: 'GET',
            url: 'data-' + val.id + '.json'
        })
        .success(function (response) {
            deferred.resolve(response);
        })
        .error(function () {
            deferred.reject();
        });

        return deferred.promise;
    });

    $q.all(promises).then(function (result) {
        $scope.resolvedData = result;
    });

});

By mapping all promises into an array based on the result of the initial call, you can create new promises within this function and resolve them in the success function. Make sure to return the actual promise!

Subsequently, you can retrieve all the resolved data using $q.all(promises). This method allows for an unlimited number of database calls based on the data fetched in the initial call.

Check out the Plunker

Edit: If possible, consider modifying the service to achieve the same result with just one call. For example:

get '/api/events' --> only returns the events
get '/api/events?includeDetail=true' --> returns both events and event details

Answer №2

To effectively handle asynchronous calls, it is important to store the response in a scope variable. This allows for easy access to the data within the scope of the controller.

 angular.module("app").controller("myCtrl", function($scope, $http) {
         $http.get("/api/events").success(function(response){
         $scope.response = response;     
        })

    });

Answer №3

I believe a possible solution could look something like this:

angular.module("app").controller("myController", function($scope, $http, $q) {

   var ids = [],
       q1 = $q.defer(), 
       q2 = $q.defer();
       d1 = $http.get("/api/data").success(function(data){
               q1.resolve(data);
               angular.forEach(data, function(id) {
                  ids.push(id); 
               });
            }).error(function(err){
                q1.reject("Oops, something went wrong!")
            });

   var promises = [];

   angular.forEach(ids, function(id) {
      var promise = $http.get("/api/data", {id:id})
                    .success(function(data){
                        q2.resolve(data);
                    }).error(function(err){
                        q2.reject("Oops, something went wrong!")
                    });
      promises.push(promise);
   });

   $q.all(promises)
     .then(function(response) {        
       console.log(response);
   });
});

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

Determining the width of an element in Chrome using jQuery

Before adding an element to the body, I require its width. The code below functions correctly in Firefox, however it does not work properly in Google Chrome. <style> .testDiv { width:150px; height:100px; } </style> <script> var di ...

Preventing jQuery plugin from overriding default settings

I have created a jQuery plugin using the nested namespace pattern, inspired by the design template found in Addy Osmani's book. The plugin is a simple gallery and everything seems to be functioning correctly. However, I am facing an issue when attemp ...

Enhance the aesthetic appeal of the imported React component with added style

I need assistance with applying different styles to an imported 'notification' component within my header component. The notification component has its own CSS style, but I want to display it in the header component with unique styling. How can I ...

Tips for stopping a click from going through a fixed element to the one in the background

My website features a fixed positioned header with a search box, overlaying content below it (thanks to the higher z-index). When I click on the search box, an event handler is triggered. However, the click response also passes through the header to the ...

The error message "Uncaught (in promise) ReferenceError: dispatch is not defined" indicates that

Currently, I am utilizing vuex with index.js and auth.js stored in the store folder. My goal is to perform a basic sign-in operation within my signin.vue by calling an action from the store. However, I encountered the error 'Uncaught (in promise) Refe ...

Checking if the iframe location has been modified using Jquery

Looking to determine if the location of an iframe has been modified. function checkLocation() { setInterval(function(){alert("Hello")},3000); if (document.getElementById("myiframe").src = 'http://www.constant-creative.com/login';) { } ...

Retrieving the value of an inner div upon clicking the outer div

I currently have a collection of button divs, each containing distinct information: <div class="button"> <div id="first"> Johny </div> <div id="second"> Dog </div> <div id="third"> Pasta & ...

Is there a way to determine the size of an array following the use of innerHTML.split?

There is a string "Testing - My - Example" I need to separate it at the " - " delimiter. This code will help me achieve that: array = innerHTML.split(" - "); What is the best way to determine the size of the resulting array? ...

Tips for removing markers from personal Google Maps

I am having trouble deleting markers from my Google Maps using my code. The markers array seems to be empty even after adding markers. Can anyone help me troubleshoot this? Thank you! When I use console.log(markers.length) in the removeMarkers() function, ...

Testing Angular 16 Component with Jasmine Spy and callFake Strategy

I've encountered an issue while trying to test my component unit. The problem arises when I call the product-list.component.ts from my product.service.ts. While my product.service.spec.ts is successful, the product-list.component.spec.ts fails as the ...

JavaScript alert system

Seeking advice on a situation. Here's the scenario I'm facing: In a messaging platform, I have an array of users who are currently online. When a new user joins the chat, I want to notify the first user in the array. If there's no response w ...

Is it possible to dynamically alter a CSS property using styled components when an onClick event occurs?

Hey there, I'm pretty new to React and currently exploring styled components for the CSS styling of my components. One of the components I've created is a button called SummonButton: const SummonButton = styled.button` height: 50px; borde ...

Clicked button redirects user to the parent URL

When the application is running on page http://localhost:3000/login, clicking a button should redirect to http://localhost:3000/. This is how I attempted it: import React from 'react'; import { Redirect } from 'react-router-dom'; impor ...

Having trouble adjusting the width and height of images to a full 100% scale

I'm currently working on an Angular and Bootstrap application where I am trying to integrate a Bootstrap carousel. However, I've encountered some resizing issues with the width and height of the images/graphs. You can view a demo of the issue he ...

"Having trouble with assetsmanager-brunch, it seems to be malfunction

Looking to move a file from the app folder to the public folder? Here is the coffee.script code snippet you need: exports.config = # See docs at https://github.com/brunch/brunch/blob/stable/docs/config.md. conventions: assets: /^app(\/|&bsol ...

What is the best way to navigate to a new webpage after clicking a button?

Currently, I am experimenting with socket io and node to show two different HTML pages. Here's what I have set up: app.get("/", function(req, res) { res.sendFile(__dirname + "/login.html") }) The scenario involves a user logging in and pressing ...

Autocomplete feature in MUI allows filtering to begin after typing at least 3 characters

I've encountered an issue with the Autocomplete MUI component I'm using to filter a list of checkboxes. The popup with options should remain open at all times, but I only want the filtering to be triggered when the user input is more than 3 chara ...

Tallying the Number of Accordion Toggle Clicks

Let me present a scenario where I have some accordions and would like to keep track of how many times the user expands each one. Could you guide me on how to implement this particular feature? Appreciate your support, Kevin ...

Adding a prefix to the imported CSS file

My React app, created with create-react-app, is designed to be integrated as a "widget" within other websites rather than functioning as a standalone application. To achieve this, I provide website owners with minified JS and CSS files that they can inser ...

Try utilizing a variety of background hues for uib progressbars

Looking to incorporate the ui-bootstrap progressbar into my template in two different colors, background included. My initial idea was to stack two progress bars on top of each other, but it ended up looking too obvious and messy, especially in the corner ...