cjs1976
cjs1976

Reputation: 35

AngularJS +how to wait for task to finish before running next task

I have still problems with my database, but I found out, that the problems come from the fact, that opening the database takes some time, but the app is not waiting till this task has finished.

Is there a way to make angular wait till the database is opened correctly before it starts the next task?

Thanks, Christian.


Update: 2016-08-08 - 03:13 pm

Thanks for all the answers. As I can see, my first idea with promises ($q) was right, but:

My app has an app.js, which is my main file. It only calls the InitDB. This should open the database. Then it should call the CreateTables, this creates the table, if it doensn't exist.

The rest of my app is splitted in 4 pages (templates). Every page has it's own controller.

So the idea was to init the db, to create the table, and then work with the database, but used over different controllers.

This won't work, because I would always need to put all of my stuff in the .then() of my initDB in the app.js???

This is my first AngularJS app, maybe this is the reason why I do a lot of mistakes...

Thanks, Christian.

Upvotes: 0

Views: 5459

Answers (4)

Pop-A-Stash
Pop-A-Stash

Reputation: 6652

One of the core concepts of Angular is working with services/factories. There is ample documentation and blogs about how these work and how to use them, but the basic idea is that these are singleton "controllers" that handle shared data and methods across your entire application. Used in combination with promises, you can easily create a service that will manage communications with your database.

angular
  .module('myApp')
  .service('DBService', DBService)
  .controller('Ctrl1', Ctrl1)
  .controller('Ctrl2', Ctrl2)
  .controller('Ctrl3', Ctrl3)
  .controller('Ctrl4', Ctrl4);

DBService.$inject = ['$q'];
function DBService($q) {
  var DBService = this;
  var DBServiceDeferred = $q.defer();
  DBService.ready = DBServiceDeferred.promise;

  // a service is only initialized once, so this will only ever be run once
  (function() {
    init();
  })();

  function init() {
    // you can use promise chaining to control order of events
    // the chain will halt if any function is rejected
    initDB()
    .then(createTablesUnlessExist)
    .then(setDbReady);
  }

  function initDB() { 
    var deferred = $q.defer();
    // simulate async db initialization
    $timeout(function() {
      deferred.resolve();
      // or reject if there is an error
      // deferred.reject();
    }, 5000);
    return deferred.promise;
  };

  function createTablesUnlessExist() {
    //create tables if needed (only happens once)
    var deferred = $q.defer();
    // simulate async table creation
    $timeout(function() {
      deferred.resolve();
      // or reject if there is an error
      // deferred.reject();
    }, 5000);
    return deferred.promise;
  }

  function setDbReady() {
    DBServiceDeferred.resolve();
  }
}

Now you have your DB setup and you don't have to worry about it anymore. You can access the DB from any controller using the service. None of the queries will run until the DB has been initialized and the tables have been created.

Ctrl1.$inject = ['DBService', '$q'];
function Ctrl1(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl2.$inject = ['DBService', '$q'];
function Ctrl2(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl3.$inject = ['DBService', '$q'];
function Ctrl3(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}
Ctrl4.$inject = ['DBService', '$q'];
function Ctrl4(DBService, $q) {
  $q.when(DBService.ready).then(function() {
    DBService.conn.query("Select something");
  });
}

Upvotes: 2

shan kulkarni
shan kulkarni

Reputation: 855

you can use $q library

example:

app.service("githubService", function ($http, $q) {
var deferred = $q.defer();

this.getAccount = function () {
    return $http.get('https://api.github.com/users/haroldrv')
        .then(function (response) {
            // promise is fulfilled
            deferred.resolve(response.data);
            // promise is returned
            return deferred.promise;
        }, function (response) {
            // the following line rejects the promise 
            deferred.reject(response);
            // promise is returned
            return deferred.promise;
        })
    ;
};

});

using above service:

app.controller("promiseController", function ($scope, $q, githubService) {
githubService.getAccount()
    .then(
        function (result) {
            // promise was fullfilled (regardless of outcome)
            // checks for information will be peformed here
            $scope.account = result;
        },
        function (error) {
            // handle errors here
            console.log(error.statusText);
        }
    );

});

Upvotes: 0

Taha Naqvi
Taha Naqvi

Reputation: 1766

Write a method that check if connection is established or not...which returns true or false.

app.controller('MainCtrl', function($scope, httpq) {
    http.get('server call method')
      .then(function(data) {
        if(data.conn==true)
       // do what u want
      //write other calls
      })
      .catch(function(data, status) {
        console.error('error', response.status, response.data);
      })

    });

Upvotes: 0

Manu
Manu

Reputation: 10944

Angular provides a service $q. A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing. Please refer the documentation https://docs.angularjs.org/api/ng/service/$q for the same. $q basically revolves around the concepts of promises. Promises in AngularJS are provided by the built-in $q service.

Upvotes: 1

Related Questions