0

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Alen Giliana
  • 2,144
  • 3
  • 17
  • 30

3 Answers3

1

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.

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54
Mohammad Sepahvand
  • 17,364
  • 22
  • 81
  • 122
  • Just to clarify, `:getData` goes into the factory as a separate method that calls and collects all other promises from within each? If so, do I still keep the `return promise.promise;` within each method? – Alen Giliana Mar 12 '14 at 06:47
  • yes, keep the promises in each method, your service methods shouldn't change. But you should really return promise.resolve(someData) from each of those methods. – Mohammad Sepahvand Mar 12 '14 at 06:55
  • I can't get anything out of aggregatedData in the controller. Does a method reference factory by this. or actually calling the factory name? `obj.getData = function (d) { return $q.all([ this.dayInWeek(d), this.nextDay(d), this.season(d), this.weekInSeason(d), this.holiday(d), this.date(d) ]); };` – Alen Giliana Mar 18 '14 at 05:05
  • This is hard to read. I created a [JSFiddle](http://jsfiddle.net/AJGiliana/jhTRg/10/). Thanks in advance – Alen Giliana Mar 18 '14 at 06:38
0

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)

Chandermani
  • 42,589
  • 12
  • 85
  • 88
  • See this too http://stackoverflow.com/questions/18217640/what-if-i-reject-resolve-multiple-times-in-kriskowals-q/18218542#18218542 – Chandermani Mar 12 '14 at 06:28
0

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) }

Alen Giliana
  • 2,144
  • 3
  • 17
  • 30