Peter Boomsma
Peter Boomsma

Reputation: 9808

.then not responding after finishing promise in Angular

I have controller in which I broadcast an event in a different controller:

getmovieController.js:

$scope.removeMovie = function(movie){
    $rootScope.$broadcast('onremoveMovieEvent', movie);
};

This is the other controller in which I call a function that requests a function inside a factory

moviesearchController.js:

$scope.$on('onremoveMovieEvent', function (event, movie) {
    movieFactory.removeMovie(movie).then(function(){
        Notification.success(movie.title + ' has been removed from your watchlist')
    })
});

This is the factory with the removeMovie function.

movieFactory.js

var factory = {}

factory.removeMovie = function (movie) {
    var deferred = $q.defer();
    $http({
        method: 'DELETE',
        url: '/movies',
        data: movie,
        headers: {"Content-Type": "application/json;charset=utf-8"}
    })
        .success(function(){
            console.log('success factory');
        })
        .catch(function(){
        });
    return deferred.promise;
};

return factory;

And finally I have a routes file that responds to the delete

movies.js

router.delete('/', function(req,res){

    pool.getConnection(function(err, connection){

        connection.query('DELETE FROM movies WHERE id= ?', [req.body.id], function(err, result) {
            if (err) {
                throw err;
            } else {
                console.log('removed')
            }
        });
        connection.release();
    });
    res.status(204).end();
});

So that's all relevant code. Now the problem. When I call the $scope.removeMovie function in the first controller the clicked record gets removed from the database and the factory shows the success factory log in the console. But I can't get in to the .then callback from the second controller

$scope.$on('onremoveMovieEvent', function (event, movie) {
    movieFactory.removeMovie(movie).then(function(){
        Notification.success(movie.title + ' has been removed from your watchlist')
    })
});

Why can't I get into the .then callback after a successfull factory function?

Upvotes: 0

Views: 159

Answers (3)

Adnan Umer
Adnan Umer

Reputation: 3689

This happens because you haven't resolving or rejecting the promise. Update your movieFactory.js

 var factory = {}

 factory.removeMovie = function (movie) {
    var deferred = $q.defer();
    $http({
        method: 'DELETE',
        url: '/movies',
        data: movie,
        headers: {"Content-Type": "application/json;charset=utf-8"}
   })
    .success(function(){
        console.log('success factory');
        deferred.resolve(/* Do send some response if necessary */);
    })
    .catch(function(){
        deferred.reject(/* Do send some response if necessary */);
    });
    return deferred.promise;
};

return factory;

You can also directly return promise returned by $http services if you are not doing any other processing.

 var factory = {}

 factory.removeMovie = function (movie) {
    return $http({
        method: 'DELETE',
        url: '/movies',
        data: movie,
        headers: {"Content-Type": "application/json;charset=utf-8"}
   });
};

return factory;

Upvotes: 0

Pawel Radomski
Pawel Radomski

Reputation: 120

I think there's missing deferred.resolve() execution inside success callback in the factory:

factory.removeMovie = function (movie) {
    var deferred = $q.defer();
    $http({
        method: 'DELETE',
        url: '/movies',
        data: movie,
        headers: {"Content-Type": "application/json;charset=utf-8"}
    })
        .success(function(response){
            console.log('success factory');
            deferred.resolve(response);
        })
        .catch(function(response) {
            deferred.reject(response);
        });
    return deferred.promise;
};

return factory;

You should also handle catch() method with: deferred.reject()

Upvotes: 1

thepio
thepio

Reputation: 6263

You should include the deferred.resolve and deferred.reject functions in your factory. So basically you do this:

factory.removeMovie = function (movie) {
  var deferred = $q.defer();
  $http({
    method: 'DELETE',
    url: '/movies',
    data: movie,
    headers: {"Content-Type": "application/json;charset=utf-8"}
  })
  .success(function(response){
    console.log('success factory');
    deferred.resolve(response); // Include response if you want
  })
  .catch(function(error){
    deferred.reject(error); // Include error if you want
  });

  return deferred.promise;
};

This will actually set the promise to success/failure and will return the response. Your then function in your controller should then work.

Upvotes: 0

Related Questions