JavaScript Angular: Return data only once several promises are fulfilled angular return data from subscribe,angular return data from observable,

I want to return data from a Service function and inject it into a controller via the routeProvider, but only once the data has been fully loaded.

app.js:

    .when('/sources', {
        templateUrl: 'views/app/source/inventory.html',
        controller: 'InventoryCtrl',
        pageTitle: 'Data Inventory',
        resolve: {
            orders: function (OrderService) {
                return OrderService.getOrders();
            },
            sources: function (SourceService) {
                return SourceService.getSources();
            }
        }
    })

SourceService:

angular.module('wp.source')
.factory('SourceService', function ($http, $q) {
    return {
        getSources: function () {
            var model = {
                sources: []
            };
            var promises = [];
            return $http.get('datasets/project.json')
                .then(function (data) {
                    if(localStorage['files'] != null) {
                        var files = JSON.parse(localStorage['files']);
                        for (var i = 0; i < files.length; i++) {
                            model.sources.push(files[i]);
                        }
                    }
                    var sources = [];
                    for (var sourceId in data.data.sources) {
                        var source = data.data.sources[sourceId];
                        source.id = sourceId;
                        sources.push(source);
                    }


                    angular.forEach(sources, function (source) {
                        promises.push($http.get('datasets/' + source.filename).then(function (datasource, resolve) {
                            var metadata = datasource.data.metadata;
                            var source = {
                                name: metadata.name,
                                address: metadata.url,
                                frequency: metadata.refresh,
                                type: metadata.type,
                                tags: metadata.tags,
                                size: metadata.size,
                                active: source.active,
                                sourceID: source.id,
                                sourceFile: source.filename
                            };
                            return source;
                        }));
                    });

                    //var finalPromise = sources.reduce(function (promise, source, index, array) {
                    //    return promise.then(function (a) {
                    //        var query = $http.get('datasets/' + source.filename)
                    //            .then(function (datasource) {
                    //                var metadata = datasource.data.metadata;
                    //                model.sources.push({
                    //                    name: metadata.name,
                    //                    address: metadata.url,
                    //                    frequency: metadata.refresh,
                    //                    type: metadata.type,
                    //                    tags: metadata.tags,
                    //                    size: metadata.size,
                    //                    active: source.active,
                    //                    sourceID: source.id,
                    //                    sourceFile: source.filename
                    //                });
                    //            });
                    //    });
                    //}, $q.when([]));
                    //
                    //finalPromise.finally(function () {
                    //    return model;
                    //})
                    $q.all(function () {
                        return model;
                    });
                });

        }
    }
});

Controller:

angular.module('wp.source')
.controller('InventoryCtrl', function ($scope, orders, sources) {
    $scope.orders = orders.data;

    $scope.gridView = true;
    $scope.rowView = false;

    $scope.allSources = sources.sources;
    $scope.shownSources = $scope.allSources;
...

Currently I have the problem that the value is injected before "model" is fully loaded. I tried to pack the subqueries into a $q.all promise, but I don't know exactly where to go from there

Any help would be appreciated

Answer:1

You want to use $q.defer() and returned the deferred promise object. You code will look something like this.

angular.module('wp.source')
.factory('SourceService', function ($http, $q) {
    return {
        getSources: function () {
            var model = {
                sources: []
            };
            var deffered = $q.defer();
            var promises = [];
            return $http.get('datasets/project.json')
                .then(function (data) {
                    if(localStorage['files'] != null) {
                        var files = JSON.parse(localStorage['files']);
                        for (var i = 0; i < files.length; i++) {
                            model.sources.push(files[i]);
                        }
                    }
                    var sources = [];
                    for (var sourceId in data.data.sources) {
                        var source = data.data.sources[sourceId];
                        source.id = sourceId;
                        sources.push(source);
                    }


                    angular.forEach(sources, function (source) {
                        promises.push($http.get('datasets/' + source.filename).then(function (datasource, resolve) {
                            var metadata = datasource.data.metadata;
                            var source = {
                                name: metadata.name,
                                address: metadata.url,
                                frequency: metadata.refresh,
                                type: metadata.type,
                                tags: metadata.tags,
                                size: metadata.size,
                                active: source.active,
                                sourceID: source.id,
                                sourceFile: source.filename
                            };
                            return source;
                        }));
                    });

                    //var finalPromise = sources.reduce(function (promise, source, index, array) {
                    //    return promise.then(function (a) {
                    //        var query = $http.get('datasets/' + source.filename)
                    //            .then(function (datasource) {
                    //                var metadata = datasource.data.metadata;
                    //                model.sources.push({
                    //                    name: metadata.name,
                    //                    address: metadata.url,
                    //                    frequency: metadata.refresh,
                    //                    type: metadata.type,
                    //                    tags: metadata.tags,
                    //                    size: metadata.size,
                    //                    active: source.active,
                    //                    sourceID: source.id,
                    //                    sourceFile: source.filename
                    //                });
                    //            });
                    //    });
                    //}, $q.when([]));
                    //
                    //finalPromise.finally(function () {
                    //    return model;
                    //})
                    $q.all(promises).then(function () {
                        deferred.resolve(model);
                    });
                });
        }
          return deferred.promise();
    }
});

EDIT As others have mentioned you need to pass your array of promises into $q.all to get this to work right. Also it's worth noting that $q.all will return an array with the results of each promise in the order they were in the promise array.

Here's a plunker demoing the use of defer.

There's more $q.defer and $q.all here in the Angular's Docs.

Answer:2

You will need to use $q.all with array of promises and return it from outer promise:

angular.module('wp.source')
.factory('SourceService', function($http, $q) {
    return {
        getSources: function() {
            var model = {
                sources: []
            };
            return $http.get('datasets/project.json').then(function(data) {

                if (localStorage['files'] != null) {
                    var files = JSON.parse(localStorage['files']);
                    for (var i = 0; i < files.length; i++) {
                        model.sources.push(files[i]);
                    }
                }

                var sources = [],
                    promises = [];

                for (var sourceId in data.data.sources) {
                    var source = data.data.sources[sourceId];
                    source.id = sourceId;
                    sources.push(source);
                }

                var promises = sources.map(function(source) {
                    return $http.get('datasets/' + source.filename).then(function(datasource, resolve) {
                        var metadata = datasource.data.metadata;
                        model.sources.push({
                            name: metadata.name,
                            address: metadata.url,
                            frequency: metadata.refresh,
                            type: metadata.type,
                            tags: metadata.tags,
                            size: metadata.size,
                            active: source.active,
                            sourceID: source.id,
                            sourceFile: source.filename
                        });
                    });    
                });

                return $q.all(promises).then(function() {
                    return model;
                });
            });

        }
    }
});
Answer:3

The code snippet for the jQuery function looks like: function addMessage() { if (textval != "") { text_string='<div class="alert-box round"><p class="text-left">' + userName + ...

The code snippet for the jQuery function looks like: function addMessage() { if (textval != "") { text_string='<div class="alert-box round"><p class="text-left">' + userName + ...

Such as: var foo = function (a, b) { return a + b; }; var bar = function (a, b) { return a * b; }; var fn = _.compose([foo, bar]); How to understand the fn?

Such as: var foo = function (a, b) { return a + b; }; var bar = function (a, b) { return a * b; }; var fn = _.compose([foo, bar]); How to understand the fn?

I have a string that is used to display text. It is initially set to null, then is updated throughout a function with status updates. I want to make sure the string is set to the correct status ...

I have a string that is used to display text. It is initially set to null, then is updated throughout a function with status updates. I want to make sure the string is set to the correct status ...

  1. test string equality bash
  2. test string equality python
  3. test string regex
  4. test string bash
  5. test string python
  6. test string equality c++
  7. test string equality java
  8. test string javascript
  9. test string length
  10. test string equality javascript
  11. test string regex javascript
  12. test string not empty bash
  13. test string contains python
  14. text string excel
  15. test string theory
  16. test string in excel
  17. test string length bash
  18. test string equality powershell
  19. test string empty bash
  20. test string contains javascript

I want to make something like Inspect Element highlight. I want to add a border to divs on mouseover. I don't want this to change the width of the div and also, there are some divs with their own ...

I want to make something like Inspect Element highlight. I want to add a border to divs on mouseover. I don't want this to change the width of the div and also, there are some divs with their own ...

  1. border with jquery
  2. add border with jquery
  3. set border with jquery
  4. change border with jquery
  5. remove border with jquery
  6. border color with jquery
  7. animate border with jquery
  8. add border with jquery css
  9. border jquery css
  10. border jquery dialog