简体   繁体   中英

AngularJS - Parsing multiple .then in controller from factory data

I have a controller calling to any set of specified methods in a factory to retrieve information on a given date. Some of the methods iterate through a JSON file to return promise. See factory below with only two methods fleshed out.

            emmanuel.factory('DayService', function($http, $q){
                var obj = {};
                    obj.dayInWeek = function(d){
                        // receives a mm/dd/yyyy string which then it converts it to day object to parse the weekday value
                        var date = new Date(d);
                            var weekday = new Array(
                                'sunday', 
                                'monday',
                                'tuesday',
                                'wednesday',
                                'thursday',
                                'friday',
                                'saturday'
                            );
                            return weekday[date.getDay()];
                    }
                    obj.season = function(d){
                        // receives a mm/dd/yyyy string parses against Calendar service for liturgical season
                        var day = new Date(d).getTime();
                        //$window.alert(day);
                        var promise = $q.defer();
                        $http.get('content/calendar.json').success(function(data) {
                            //$window.alert(data.calendar.seasons.season.length);
                            for (var i=0; i<data.calendar.seasons.season.length; i++){
                                var start = new Date(data.calendar.seasons.season[i].start);
                                var end = new Date(data.calendar.seasons.season[i].end);
                                end.setHours(23,59);
                                //$window.alert(start +'-'+  end +' || '+ day);
                                if (day >= start && day <= end){
                                    //$window.alert(data.calendar.seasons.season[i].name);
                                    var temp = data.calendar.seasons.season[i].name;
                                    promise.resolve(temp);
                                    //$window.alert(promise);
                                    break;
                                }
                            }
                        });

                        return promise.promise;
                    }
                    obj.weekInSeason = function(d){
                        /*...
                            return promise.promise;
                        */
                    }
                    obj.holiday = function(d){
                        /*...
                            return promise.promise;
                        */
                    }
                return obj;
            });

I was tried to write multiple temp.then(function(var) {...}); for each of the methods to store the values in a $scope.date model but to my dismay only the last .then instance would store the value.

            emmanuel.controller('WeekdayMorning', function($scope, DayService){
                var tempWeek = DayService.weekInSeason(today);
                var tempSeason = DayService.season(today);

                tempWeek.then(function(week) {
                    $scope.date = {weekNum: DayService.weekInSeason(today)};
                    $scope.date = {oscWeek: week % 2};
                });

                tempSeason.then(function(season) {
                    $scope.date = {season: DayService.season(today)};
                });
            });

How can I retrieve the data from the factory promise either individual methods or as a complete $scope.date model?

Use $q.all instead ( Official documentation for $q ):

getData: function (today) {
                return $q.all([
                   DayService.weekInSeason(today),
                   DayService.season(today)
                ]);
          };

and then use then like this:

getData(today).then(function(aggregatedData){
$scope.resultFromWeekInSeason = aggregatedData[0];
$scope.resultFromSeason = aggregatedData[1];
});

Note that this will only resolve when both calls have succeeded, the calls take place simultaneously.

Promise once resolved to a value, i believe cannot change but you are trying to resolve the same promise again and again in for loop with different values. I am not sure how your scenario works, but you can use the promise notification mechanism where you can do this inside the for loop

promise.notify(temp);

and after the loop do

promise.resolve({});

You can catch progress in the third parameter of then

then(successCallback, errorCallback, notifyCallback)

The other option is to collated the temp values into an array inside a for loop.

and then finally to promise.resolve(allTemps)

Thank you all for the help. The issue I was having was related to repeatedly declaring the model on the $scope and not multiple promises.

Every time I re-declared $scope.date= {attr : ...} I eliminated all the previous attribute values, therefore only leaving the last declaration to contain any values. The right way to declare multiple attribute values to Angular $scope model is

$scope.date = { weekday: DayService.dayInWeek(today), season: DayService.season(today), weekNum: week, oscWeek: week % 2, holiday: DayService.holiday(today), nextDay: DayService.nextDay(today) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM