Using Angular's $q service in the run block

I have a scenario where I need to load data from local files using the global loadJSON function (though it's not mandatory, it's recommended).

Once the data is loaded from all the documents, I want to print the string 'i ve loaded'.

The issue arises when I start using data from the 'x' service before it is fully loaded into memory from the files.

How can I ensure that I wait for the data to be loaded before proceeding with rendering the pages and executing other tasks?

It seems like using $q might be the solution, but how should I implement it?

function loadJSON(file, callback) {
  var doc = new XMLHttpRequest();
  doc.overrideMimeType("application/json");
  doc.open('GET', file, true);
  doc.onreadystatechange = function () {
    if (doc.readyState == 4 && doc.status == "200") {
      callback(JSON.parse(doc.responseText));
    }
  };
  doc.send(null);
}

angular
  .module('msApp')
  .factory('service.x', [
    function () {
      var _database = {};

      return {
        get: function (k1, k2) {
          return _database[k1][k2];
        },

        load: function (list, callback) {
          var length = list.length;
          var loaded = 0;

          function addToDB(name) {
            var url = './assets/{0}.json'.format(name);
            loadJSON(url, function (json) {
              _database[name] = json;

              loaded++;
              if (length === loaded && callback) callback();
            });
          }

          for (var i = 0; i < list.length; i++) {
            addToDB(list[i]);
          }
        }

      };
    }
  ]);

angular
  .module('msApp', [])
  .run([
    '$rootScope',
    'service.x',
    function ($rootScope, x) {

      x.load($rootScope.services, function () {
        console.log('i ve loaded')
      });

    }
  ])
  .config(function ($routeProvider) {

    $routeProvider
      .when('/sign', {
        templateUrl: '../views/sign.html',
        controller: 'signCtrl'
      })
      .when('/a', {
        templateUrl: '../views/a.html',
        controller: 'aCtrl'
          .otherwise({
            redirectTo: '/signin'
          });
  });

Answer №1

Controllers have the ability to accept a resolve parameter, which allows you to inject dependencies into the controllers. These dependencies can be raw objects or promises, blocking the instantiation of the controller until they are resolved:

$routeProvider.when('/routeA', {
  templateUrl: '/routeA.html',
  controller: 'controllerA',
  resolve: {
    mydata: ['service.x', function (x) {
      return x.load($rootScope.services);
    }]
  }
});

The load and addToDb functions must be modified to return promises:

load: function (list) {
  // initialize variables

  function addToDb(name) {
    var deferred = $q.defer();
    // build URL from name

    loadJson(url, function (data) {
      // save to database

      deferred.resolve(data);
    });

    return deferred.promise;
  }

  var promises = [];
  for (var i = 0; i < list.length; i++) {
    promises.push(addToDb(list[i]));
  }

  return $q.all(promises);
}

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

What is the correct way to utilize Array.reduce with Typescript?

My current approach looks something like this: [].reduce<GenericType>( (acc, { value, status, time }) => { if (time) { return { ...acc, bestValue: valu ...

Load Materialize autocomplete with data from a JSON file

After hours of research, I am struggling to populate my autocomplete input using the Materialize plugin for a website project. Since I am not well-versed in json or ajax, implementing the original example from the documentation with static data has been qu ...

Implementing a React app mounting functionality upon clicking an HTML button

Is there a way to mount a react application by clicking on a standard html button outside of the application itself? My index.html layout is as follows: <div id="app"></div> <button id="button-root">Live chat</butt ...

Inventive website concept (far from ordinary, and not a plea for coding assistance)

Once again, I want to clarify that I am not asking for someone to code this idea for me. I am seeking advice from experienced web developers on whether or not my concept is achievable, as it involves some complex issues (at least in my opinion). If this po ...

Deactivate certain choices in React Select

Encountering difficulties disabling specific options in a large list within a React Select component. A total of 6,500 options are loaded into the select element. Initially, there were issues with search functionality lagging, but this was resolved by impl ...

Updating a marker in real-time using API response

I'm trying to create a simple web application that allows users to enter a city name in an input box, which then triggers the updateMap function to geolocate and map the city with a marker. After mapping the city, another function called updateTemp is ...

Create a function called "insertEvent" that will insert a new event on a specified date

Below is the data structure for storing affairs according to years, months, and days: let affairs = { 2018: { 11: { 29: ['task111', 'task112', 'task113'], 30: ['task121', 'ta ...

angularjs and cakephp working together to handle a request

I've implemented a method in the UsersController to add new users to the database. In the cakephp ctp views, everything seems fine as the request isn't being black-holed and I'm using 'post' for this purpose. However, when I transi ...

Introducing a fresh parameter to initiate and end Server Sent Events

Assistance needed. I have implemented Server Sent Events to dynamically update a website using data from a database. Now, I aim to send a new parameter ('abc.php/?lastID=xxx') back to the PHP script based on information received in the previous ...

What are the best methods to prevent infinity printing?

While attempting to create a clock that displays time in real-time after adding a time zone, I encountered an issue where the time was being printed multiple times. My objective is to have it printed once and dynamically change according to the different t ...

The response received from the server was a 404 status () indicating that the resource failed to load

I'm encountering an issue while loading from the web service, and receiving the following error: Failed to load resource: the server responded with a status of 404 () Your help would be greatly appreciated. You can also access the code on JSFiddl ...

Create a new tab without triggering the pop-up blocker by utilizing an iframe's JavaScript event

I currently have an iframe embedded in a webpage. Once data is successfully sent to the server within the iframe, the server responds with a new URL to be opened either in a new tab or the parent window. The main issue I am encountering is that the brows ...

Creating a javascript function to update content on click

Recently, I've been designing a webpage and encountered an issue. I want the text in a specific area to change whenever a user clicks on a link. Below is the code snippet related to the section I want to modify using a JavaScript function. <div id ...

I'm having some trouble with this error while trying to install nodemon globally using npm. How can I troub

Currently, I am diving deep into node js and express. However, I have encountered persistent error messages while trying to install 'nodemon'. What type of error message am I dealing with here? How can I troubleshoot and resolve this issue? Whic ...

Conceal the loading image once the AJAX function has been successfully

I've been trying to figure out a way to load heavy images after an ajax call using animated GIF as a pre-loader, but haven't found a satisfactory solution yet. Here's the code snippet I'm currently using: function loadProducts(url) { ...

Extract items from javascript array based on their index value

Recently I came across a javascript array var countries = ["India","USA","China","Canada","China"]; My goal is to eliminate "China" only from the 2nd position while keeping the rest intact. var countries = ["India","USA","Canada","China"]; I am see ...

Transform the JSON response from MongoDB into a formatted string

var db = mongoose.connection; const FoundWarning = db.collection('warning').find({UserID: Warned.user.id, guildID: message.guild.id}).toArray(function(err, results) { console.log(results); }) I have been attempting to ...

Maintain the previous state in AngularJS using ui-router

My goal is to preserve the current state of the view, not just the URL and parameters. I am looking to save the entire view along with its scopes. Specifically, I am working on creating a search system similar to Facebook's, but with a unique twist. I ...

Checking for duplicate entries in an array created with the Angular form builder

I am currently utilizing angular6 reactive form with form builder and form array. The issue I am encountering is duplicate subject entries from the drop down in the form array. How can I implement validation to prevent duplicate entries in the form array? ...

The function '$.fn.<new_function>' is not a valid function in jQuery

UPDATE: code link with enhanced formatting: UPDATE: code upgraded with enhancements from JSHint http://pastebin.com/hkDQfZy1 I am attempting to utilize $.fn to establish a new function on jQuery objects by this method: $.fn.animateAuto = function(x,y) { ...