1

I am trying to save the tags for selected items list using api. In api I store the tags only once for the first selected item and for the rest I do not store the items instead I create the entry as shared. Problem is: the first selected item hits the api and before storing the data other selected items also gets hit and I am not able to provide the shared reference as the data is not been stored yet.

Things I have tried -

This is my controller:

let selectedQstCount = $scope.selectedQuestion.length;
for (i = 0; i < selectedQstCount; i++) {
    var params = {
        "jsonString": callbackData,
        "questionNo": $scope.Questionlst.find(a => a.QuestionId == $scope.selectedQuestion[i].id).QuestionNo,
        "projectName": $scope.ProjectName,
        "projectId": $scope.ProjectId,
        "questionId": $scope.selectedQuestion[i].id,
        "newCodeFrame": ($scope.attachCodeFrame == "No" ? "FALSE" : "TRUE"),
        "sharedQstId": $scope.sharedQstId,
        "groupName": $scope.groupName
    }
    var defer = $q.defer();
    CodeFrameJsonfactory.CodeFrameUpload(params, function (data) {
        //success
        $q.resolve(data);
    }, function (callbackData) {
        //error
        inform.clear();
        inform.add(callbackData.Message, { ttl: -1, type: 'danger' });
    });
    return defer.promise;
}

This is my factory:

CodeFrameUpload: function (params, successCallback, errorCallback) {
    var deferred = $q.defer();
    $http({
        method: 'POST',
        url: APIUrls.getUrl("uploadCodeFrame"),
        data: params,
        headers: {
            'Content-Type': 'application/json'
        },
        cache: false
    }).success(function (data) {
        deferred.resolve(data);
        successCallback(data);
    }).error(function (data) {
        deferred.reject(data);
        errorCallback(data);
    });
    return deferred.promise;
},

I have also tried using angular.forEach with deffered.

I want achieve is, until CodeFrameUpload function is completed I do not want to hit it again.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • The `.success` method has been [removed from the AngularJS framework](https://stackoverflow.com/questions/35329384/why-are-angularjs-http-success-error-methods-deprecated-removed-from-v1-6/35331339#35331339). – georgeawg Nov 27 '19 at 14:29

1 Answers1

0

Return a data promise:

CodeFrameUpload: function (params) {
    return $http({
        method: 'POST',
        url: APIUrls.getUrl("uploadCodeFrame"),
        data: params,
        headers: {
            'Content-Type': 'application/json'
        },
        cache: false
    }).then(function(response) {
        return response.data;
    });
},

Map the returned promises:

var promiseArr = $scope.selectedQuestion.map(question => {
    var params = {
        "jsonString": callbackData,
        "questionNo": $scope.Questionlst.find(a => a.QuestionId == question.id).QuestionNo,
        "projectName": $scope.ProjectName,
        "projectId": $scope.ProjectId,
        "questionId": question.id,
        "newCodeFrame": ($scope.attachCodeFrame == "No" ? "FALSE" : "TRUE"),
        "sharedQstId": $scope.sharedQstId,
        "groupName": $scope.groupName
    }
    return CodeFrameJsonfactory.CodeFrameUpload(params);
});

Use $q.all:

$q.all(promiseArr).then(function(dataArr) {
    console.log(dataArr);
}).catch(function(errResponse) {
    console.log(errResponse);
});

$q.all returns a single promise that will be resolved with an array/hash of values, each value corresponding to the promise at the same index/key in the promises array/hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value.

For more information, see


Update

The above example executes the HTTP requests in parallel.

To chain promises sequentially:

var paramsArr = $scope.selectedQuestion.map(question => ({
        "jsonString": callbackData,
        "questionNo": $scope.Questionlst.find(a => a.QuestionId == question.id).QuestionNo,
        "projectName": $scope.ProjectName,
        "projectId": $scope.ProjectId,
        "questionId": question.id,
        "newCodeFrame": ($scope.attachCodeFrame == "No" ? "FALSE" : "TRUE"),
        "sharedQstId": $scope.sharedQstId,
        "groupName": $scope.groupName
}));

var sequentialPromise = paramsArr.reduce( (promise, paramsObj) => {
    promise.then(function(dataArr) {
        var singlePromise = CodeFrameJsonfactory.CodeFrameUpload(paramsObj);
        return $q.all([...dataArr, singlePromise]);
    },
    $q.when([])
);

sequentialPromise.then(function(dataArr) {
    console.log(dataArr);
});
Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95