Search code examples
angularjsangularjs-service

Angularjs promise with jquery ajax


The factory sends data to the server and its processed correctly but after that the ".then" in the controller is not being called below.

Kindly let me know why the "then" part is not being executed in the controller here after the successful ajax call.

factory

myapp.factory('startCampFactory',function($http,$q,$rootScope){

        return {

            startNewCampaign : function(){

            var e = $("input#email");
            var email = e.val();
            var campname = $("input#campaignname").val();
            var about = $("textarea#about").val();
            var tamt = $("input#targetamount").val();
            var edate = $("input#enddate").val();
            var invitees = $("input#invitees").val();
            var file_data = $("#file").prop("files")[0];
            var form_data = new FormData();     
            form_data.append("file",file_data);
            form_data.append("email",email);
            form_data.append("campaignname",campname);
            form_data.append("about",about);
            form_data.append("targetamount",tamt);
            form_data.append("enddate",edate);
            form_data.append("invitees",invitees);
            console.log(email+about+campname);
            var deferred = $q.defer();
            $.ajax({
                type:'POST',
                url: "http://localhost:8080/startcampaign",
                data:form_data,
                contentType:false,
                processData:false,
                cache:false,
                dataType:"json",
                success:function(msg,status)
                {
                    //if(status=="success")

                        deferred.resolve("success");
                        $rootScope.$apply();
                },
                        error:function()
                        {

                            deferred.reject();
                            $rootScope.$apply();
                        }
                });
                return deferred.promise;
                }
        }       
    });

conrtoller

function startCampCtrl($scope,startCampFactory)
{
    $scope.startcamp = function(){
        $("#submit").prop('disabled',true);

        startCampFactory.startNewCampaign().then(function(d){
            alert("here");
            var temp = "<div class=\"alert alert-dismissable alert-success\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button> <strong>Campaign Saved successfully</strong></div>";
                $(temp).prependTo("#startcamp");
                $("#submit").prop('disabled',false);
                $("input#campaignname").val('');
                $("textarea#about").val('');
                $("input#targetamount").val('');
                $("input#enddate").val('');
                $("input#invitees").val('');
                $("input#file").val('');
        },
        function(){//On error
            var temp = "<div class=\"alert alert-dismissable alert-warning\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button> <strong>Campaign could not be saved, please try again</strong></div>";
                $(temp).prependTo("#startcamp");
                    $("#submit").prop('disabled',false);
        });

    }

}

Solution

  • You're using $.ajax() to trigger the call. The correct way to do it is to use the $http service. When a call is made through that service an $apply is automatically trigerred , and all your promises will get executed in that $apply cycle.

    If you want to trigger the promises from your success function inside the $.ajax() call, I suppose you can do it inside an $apply cycle:

    .....
    success:function(msg,status){
                       $rootScope.$apply( function() { 
                            deferred.resolve("success"); 
                         });
    }
    ....
    

    Here is the working fiddle with correct way to invoke promise