DeltaWeb DeltaWeb - 5 months ago 113
AngularJS Question

How to make a loop of synchronous http request with $http?

I have a list of video objects, each object has a link and few other attributes . I've built a loop that goes through this list and upload those videos via their links, the service I'm currently using, doesn't support uploading multiple videos at one time, I need to wait the 1st video to upload after that I need the 2nd to upload ..etc

Here's the code responsible for this :

$scope.upload = function(){
$scope.videoList.forEach(function(video){
video.state = "Downloading"
$scope.msg = "The video is downloading"
$http.post("/download",{link : video.link,title : video.title}).then(function(resp){
$scope.msg = "The video has been downloaded on the server, it will now start uploading"
var filen = resp.data["fn"]
var title = resp.data["title"]
video.state = "Uploading"
$http.get("/uploadVid?file=" + filen +"&title=" + title).then(function(resp){
if (resp.data == "0002"){
alert( "You didn't authorize the App yet, please authorize it to be able to use it .")
}
if (resp.data == "000X"){
alert("An error occured, please retry .")
}
else{
$scope.msg = "the video uploaded, here's the link: " + resp.data
video.state = "Done"
video.link = resp.data
}
} )
})

}) }


What happens here, is that for each video we download it on the server, once it's downloaded, it's uploaded to the video hosting service (youtube in our case) . This should work fine, but due to the async nature of the
$http
service calls, they all start downloading at the same time and uplaod at the same time .

The loop doesn't wait for the iteraion to finish and goes directly to the next iteration . I want this to be synchronous, videos shouldbe downloaded and uploaded one by one . I'd prefer to not use Promises Interface, I'm at a rush and I don't know much about them . If you do please explain it as much as you can .

Answer

You don't want to make the requests synchronous. You do want to make them sequential. (A synchronous ajax request is one that holds up the JavaScript UI thread — and usually the browser's UI, at least within that tab — waiting for the ajax operation to complete. That makes for a poor user experience. Doing them sequentially just means doing one after another, e.g., in sequence rather than parallel.)

The usual way to do that is to track which one you're on, do your processing, and then when done with the processing of that one, move on to the next; see comments:

$scope.upload = function() {
    // Grab the array and start with index = 0
    var videos = $scope.videoList;
    var index = 0;
    if (videos.length) {
        // Start the process
        next();
    }

    // Our handler for each video
    function next() {
        // Get the video
        var video = videos[index];
        video.state = "Downloading"
        $scope.msg = "The video is downloading"
        $http.post("/download", {
            link: video.link,
            title: video.title
        }).then(function(resp) {
            $scope.msg = "The video has been downloaded on the server, it will now start uploading"
            var filen = resp.data["fn"]
            var title = resp.data["title"]
            video.state = "Uploading"
            $http.get("/uploadVid?file=" + filen + "&title=" + title).then(function(resp) {
                if (resp.data == "0002") {
                    alert("You didn't authorize the App yet, please authorize it to be able to use it .")
                }
                if (resp.data == "000X") {
                    alert("An error occured, please retry .")
                } else {
                    $scope.msg = "the video uploaded, here's the link: " + resp.data
                    video.state = "Done"
                    video.link = resp.data

                    // Do the next video now we've finished this one
                    if (++index < videos.length) {
                        next();
                    }
                }
            })
        })
    }
}

Note: Dashed off, may not have all i's crossed and t's dotted, but presumably the fundamentals are clear.

Comments