issue with angular promise not resolving properly

In my current project, I am trying to ensure that a promise resolves after making a query on Firebase. The goal is to retrieve specific keys from one table and then iterate through another table to fetch the desired artwork.

artistFactory.js

'use strict';

angular.module('artvoicesApp')
  .factory('Artist', function(localStorageService, FIREBASE_URL, $q) {

    var artistData = {};
    var userKey = localStorageService.get('userKey');
    var accountKey = localStorageService.get('accountKey');
    var artistRef = FIREBASE_URL.child('v2/artist');
    var accountRef = FIREBASE_URL.child('v2/account/' + accountKey);
    var userRef = FIREBASE_URL.child('v2/user/' + userKey);

    artistData.addArtist = function(artistName) {
      var artist = artistRef.push();
      accountRef.child('artists/' + artist.key()).set(true);
      userRef.child('artists/' + artist.key()).set(true);
      artist.set({name: artistName});
      artist.child('users/' + userKey).set(true);
      artist.child('accounts/' + accountKey).set(true);
    };

    artistData.getArtistKeys = function() {
      var artistKeys = [];
      var defer = $q.defer();
      accountRef.child('artists').once('value', function(snapshot) {
        snapshot.forEach(function(childSnapShot) {
          artistKeys.push(childSnapShot.key());
        });
        defer.resolve(artistKeys);
      });
      return defer.promise;
    };

    artistData.getArtists = function(artistKeys) {
      var artistObj = {};
      var artistRef = FIREBASE_URL.child('v2/artist');
      var defer = $q.defer();

      artistKeys.forEach(function(artist) {
        artistRef.child(artist).once('value', function(snapshot) {
          artistObj[artist] = snapshot.val();
        });
        defer.resolve(artistObj);
      });
      return defer.promise;
    };

    return artistData;
  });

artwork.controller.js

Artist.getArtistKeys().then(function(artistKeys) {
  Artist.getArtists(artistKeys).then(function(artists) {
      vm.artists = artists;
      console.log(vm.artists);
  });
});

If I assign vm.artwork with a timeout, it returns the correct data.

Answer №1

Your issue is as follows:

  When looping through the artistKeys using forEach, you are resolving the defer object before the asynchronous call to retrieve data from the Firebase database completes. This results in the assignments to artistObj happening after the defer.resolve() call.

To solve this problem, you need to map your artists to promises, wait for all promises to resolve, and then return a single promise containing the artist objects.

artistData.getArtistKeys = function(artistKeys) {
  var artistObj = {};
  var artistRef = FIREBASE_URL.child('v2/artist');
  var allPromises = artistKeys.map(function(artist) {
    var childDefer = $q.defer();
    
    artistRef.child(artist).once('value', function(snapshot) {
      artistObj[artist] = snapshot.val();
      childDefer.resolve();
    });
    
    return childDefer.promise();
  });

  var defer = $q.defer();
  
  $q.all(allPromises).then(function() {
    defer.resolve(artistObj);
  });
  
  return defer.promise();
}

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

unique scope within a personalized directive

Hi, I'm trying to understand isolated scope in custom directives Here is an example of my directive: restrict: 'E', scope: {}, template: '<input type="file" ng-model="myFile" />{{myFile.name}}', link ...

Tips for effortlessly moving content by dragging and dropping it into a text box

Before attempting to create something, I want to verify its feasibility. Begin with a text area that can be pre-filled with text and allow users to add or delete text. Alongside the text area, there are small elements that can be images or HTML components ...

The data from my ajax code is not being successfully transmitted to the database

I'm having trouble using ajax to add data to the database. I'm not sure if the issue lies in the ajax code or the PHP code. Here is a snippet of my code: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></ ...

Exploring techniques to maintain search functionality on altered display columns in DataTables.js

How can I ensure that the search functionality works properly on the modified render column in DataTables.js? In the code snippet provided below, my attempts to search data within the render columns are not yielding any results. $('#release-table& ...

Exploring a new path with Angular

I'm attempting to dynamically change the sp-right class to sp-left in Angular: Html <span class="sp-right"> <label> Number: </label> </span> Directive app.directive("buttonThatTrigger", function () { ...

Every time I load the script, my global variables reset. How can I prevent this constant refreshing?

As I work on completing a prototype for my system, I am facing an issue with global variables reinitializing every time the script reloads. Currently, I am not using localStorage and simply need a quick solution to prevent the variables and functions from ...

The operation to set a nickname in Discord.js was unsuccessful due to insufficient permissions

Recently, I started using discord.js to create a simple bot. Whenever I try to change the nickname by calling message.member.setNickname("Another Nickname").then(console.log, console.log); I receive the following error message: { name: ' ...

Sending data to the server using AngularJS 1.x and Typescript

I am encountering an issue where the header values I'm trying to post to the server are not properly embedded in the request header, resulting in incorrect answers. I understand that there is a mistake in my approach, but I can't seem to pinpoint ...

What is the process of choosing a language (English/French) within a pop-up?

<body style="text-align:center"> <h2>Popup</h2> <div class="popup" onclick="myFunction()">Interact with me to show/hide the popup! <span class="popuptext" id="myPopup">A Simple Popup!</span> </div> <script& ...

Using the i18next Module for Localization in ExpressJS and Front-End Development

I am currently integrating the i18next module into my NodeJs/ExpressJS web application. All the translation files are stored in the /locales directory. According to information from i18next.com, it can also be utilized on the client side. <script typ ...

Pick and modify a particular component in ReactJS

Currently, I am working on a project in ReactJS where I am attempting to toggle the colors of two buttons. While I have successfully set the active state property of the selected button, I am facing challenges with changing the style of another button (cal ...

Leveraging the power of Angular's ng-repeat for iterating through multi-dimensional arrays

Currently, I am in the process of developing a game and utilizing NG repeat to dynamically insert divs based on the number of letters and words present. For instance, if the answer to a question in the game is "Clean Sheet," I would like NG-Repeat to gener ...

"Utilizing the ui-grid feature to dynamically apply cell filters

I am looking to utilize ui-grid to create a column with a dynamic cellFilter that can be updated on the fly, from 'number' to 'currency', for example. I attempted changing the parameter cellFilter within the column but it does not refle ...

What is a way to hide or exclude tabs when there is no content to display for a particular tab in Vue?

I'm new to javascript and Vue, and I'm trying to figure out how to hide tabs that don't contain any information. I want to display only the tabs that do have information. Can someone please help me with this? I automatically pull images bas ...

Showcase information from APIs using Vue.js

I am facing an issue where I am able to fetch data correctly from the API, but I am unable to display it. When I manually input items, they are displayed, but the items fetched from the API remain invisible. I even attempted to move the API call directly i ...

Can you explain the significance of this { logic } syntax in JavaScript (excluding objects)?

I recently came across this interesting code snippet in an open source ReactJS project on GitHub. It was found in the file: react.development.js { ReactDebugCurrentFrame.setExtraStackFrame = function (stack) { { currentExtraStackFrame = ...

Button inside form not triggering jQuery click event

Within a form, I have included a button that looks like this: <form> <input type="text" /> <input type="password" /> <button type="button" class="btn-login">Log in</button> </form> I want to activate the butt ...

"How can I perform a expressjs database query based on a specific user's

app.get('/user/:id', function(req, res){ fetchData(req.params.id, res); }); function fetchData(id, res) { connection.query('SELECT * FROM data WHERE name = ?' , function(err, rows){ res.render('users', {users ...

Steps to Deactivate Dates in React Beautiful Dates Component

I found this amazing Calendar library at . Within the library, I am utilizing the <DatePickerCalendar /> component. Currently, I have stored three dates in an array: [date1, date2, date3] My goal is to disable these specific dates in the calendar s ...

"Unable to get elements by tag name using the getElementsByTagName method in

function updateLayout() { var para = document.getElementsByTagName("p"); para[0].style.fontSize = 25; para[1].style.color = "red"; } <p>Text in paragraph 1</p> <p>Text in paragraph 2</p> <p>Text in paragraph 3</p& ...