tidydee
tidydee

Reputation: 123

ng-change only triggers once inside a ng-repeat -- Angular

I am connecting to the Yahoo weather service API and made a little simple weather app using Angular. I also created a F - C temperature converter that triggers with the help of ng-change(). However for some reason this only works once on initialization. For some reason I can not make sense why ng-repeat would only fire once inside an ng-repeat. Please see code below. Any help would be appreciated.

***I should mentioned that when I placed a "debugger" inside my function called, changedTemperatureTo, it triggers the "debugger" when I convert from F->C, but the "debugger" doesn't even trigger from C->F, the second time round. By second time around, I mean after I flipped the radio button from F->C the first time. When I flip it back, nothing happens - Debugger doesn't trigger.

VIEW:

{{date}}

<span ng-repeat="temp in temperatureNames">
  <input type="radio" name="selectedTemperatureNamed" ng-model="selectedTemperatureName" ng-value="temp" ng-change="changedTemperatureTo(temp)"/> {{temp}}
</span>

<select ng-model="sort">
  <option value="cityNameForForecast(td)">City</option>
  <option value="high">High</option>
  <option value="low">Low</option>
</select>
<input type="checkbox" ng-model="reverse"/> <small>*Check to Reverse Order</small>


<div ><br>
    <table class="tg">
        <thead>
           <tr >
                <th class="tg-031e"></th>
                <th class="tg-031e"></th>
                <th class="tg-031e"></th>
                <th class="tg-031e">High</th>
                <th class="tg-031e">Low</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="td in forecastAll | orderBy:sort:reverse">
                <th class="tg-031e"><a href="#/weather/city/{{cityNameForForecast(td)}}">{{cityNameForForecast(td)}}</a></th>
                <th class="tg-031e"><img src="http://l.yimg.com/a/i/us/we/52/{{ td.code }}.gif"></th>
                <th class="tg-031e">{{td.text}}</th>
                <th class="tg-031e">{{td.high}}</th>
                <th class="tg-031e">{{td.low}}</th>
            </tr>
        </tbody>
    </table>

</div>

CONTROLLER:

/*global angular */

var weatherControllers = (function () {
    var weatherControllers = angular.module('weatherControllers', []);

    // Declare the application controller and inject the scope reference.
    weatherControllers.controller('AppCtrl', ['$scope', function ($scope) {
        // Define the title model.
        $scope.title = "AngularJS Tutorial - Yahoo Weather App";
    }]);
    // Inject the scope and new weatherService reference into the controller.
    weatherControllers.controller('ListCtrl', ['$scope', 'weatherService', function ($scope, weatherService) {
      // Define the forecast data.  
    }]);

    // Inject the scope and new weatherService reference into the controller.
    weatherControllers.controller('WeatherCtrl', ['$scope', 'weatherService',
                                  function ($scope, weatherService) {
                                      // Define the forecast data.      
                                      // forcastOne >
                                      weatherService.getWeather('Vancouver').success(function (data) {
                                        $scope.forecastVan = weatherService.getForecastFromData(data);
                                        console.log("forecastVan");
                                        console.log($scope.forecastVan);
                                        // console.log($scope.forecastVan[0]);
                                        // console.log("$scope.forecastVan[0]['date']");
                                        // console.log($scope.forecastVan[0]['date']);
                                        $scope.forecastDate = $scope.forecastVan[0]['date'];

                                        weatherService.getWeather('Honolulu').success(function (data) {
                                          $scope.forecastHon = weatherService.getForecastFromData(data);
                                          console.log("forecastHon");
                                          console.log($scope.forecastHon);
                                          console.log($scope.forecastHon[0]);
                                          weatherService.getWeather('San Diego').success(function (data) {
                                            $scope.forecastSan = weatherService.getForecastFromData(data);
                                            console.log("forecastSan");
                                            console.log($scope.forecastSan);
                                            console.log($scope.forecastSan[0]);
                                            weatherService.getWeather('Havana Cuba').success(function (data) {
                                              $scope.forecastHav = weatherService.getForecastFromData(data);
                                              console.log("forecastHav");
                                              console.log($scope.forecastHav);
                                              console.log($scope.forecastHav[0]);
                                              // Create index model
                                              $scope.forecastAll = [$scope.forecastVan[0], $scope.forecastHon[0], $scope.forecastSan[0], $scope.forecastHav[0]]
                                            });
                                          });
                                        });
                                      });

                                      $scope.cityNameForForecast = function (forecast) {
                                        if ($scope.forecastVan[0] == forecast) {
                                          return 'Vancouver';
                                        }
                                        else if ($scope.forecastHon[0] == forecast) {
                                          return 'Honolulu';
                                        }
                                        else if ($scope.forecastSan[0] == forecast) {
                                          return 'San Diego';
                                        }
                                        else if ($scope.forecastHav[0] == forecast) {
                                          return 'Havana Cuba';
                                        }
                                      };


                                      // Temperature
                                      $scope.temperatureNames = ['C', 'F'];

                                      $scope.selectedTemperatureName = $scope.temperatureNames[1];

                                      $scope.changedTemperatureTo = function (temperatureName) {
                                          // debugger;
                                        if (temperatureName == 'C') {
                                          $scope.forecastAll = weatherService.arrayToCelsius($scope.forecastAll);
                                        }
                                        else if (temperatureName == 'F') {
                                          $scope.forecastAll;
                                        }
                                      };
                                  }]);
    // Inject scope, $routeParams, and cardService  
    weatherControllers.controller('DetailCtrl', ['$scope', '$routeParams', 'weatherService',
                                  function ($scope, $routeParams, weatherService) {
                                    weatherService.getWeather($scope, $routeParams.cityID);
                                    $scope.cityName = $routeParams.cityName;

                                    weatherService.getWeather($routeParams.cityName).success(function (data) {
                                      $scope.forecast = weatherService.getForecastFromData(data);
                                    });
                                    $scope.temperatureNames = ['C', 'F'];
                                    $scope.selectedTemperatureName = $scope.temperatureNames[1];

                                  }]);

    return weatherControllers;
}());

SERVICES:

weatherApp.factory("weatherService", function ($http) {
    'use strict';
    return {
        doSomething: function ($scope) {
        },
        getWeather: function (city) {
            var url = this.getUrlForCity(city);
            return $http.get(url);
        },
        getUrlForCity: function (city) {
            // Weather codes:
            var weatherCodes = {'Vancouver': 'CAXX0518', 'Honolulu': 'USHI0026', 'San Diego': 'USCA0982', 'Havana Cuba': 'CUXX0003'}

            var city     = weatherCodes[city] // Now on can call all cities at once
            var yahooAPI = "'http://weather.yahooapis.com/forecastrss?p=";
            var format   = "'&format=json&diagnostics=true&callback=";
            var yql      = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20rss%20where%20url%3D";
            var url      = yql + yahooAPI+ city + format;
            return url;
        },

        getForecastFromData: function (data) {
            try {

                var stringified = JSON.stringify(data);          // Convert to a string.
                stringified = stringified.split("\\n").join(""); // Remove new line '/n'.
                var listing = JSON.parse(stringified);           // Convert to object.
                var forecast = [];                               // Store 5 day forecast.
                var forecastDate = [];                           // Stores forecast date
                for (var result in listing) {
                    for (var item in listing[result].results) {
                        for (var day in listing[result].results.item.forecast) {
                            forecast.push(listing[result].results.item.forecast[day]);
                        }
                    }
                }
            }
            catch (error) {
                alert("Weather reading error:" + error.name + ": "
                    + error.message);
            }
            return forecast;
        },

        arrayToCelsius: function (forecastArray) {
            for (var i = 0; i < forecastArray.length; i++) {
                forecastArray[i]['high'] = this.getCelsius(forecastArray[i]['high']);
                forecastArray[i]['low'] = this.getCelsius(forecastArray[i]['low']);
            }

            return forecastArray;
        },

        getCelsius: function (fahrenheit) {
            var fTempVal = this.getForecastFromData(fahrenheit);
              // debugger;
            // $scope.celsius = this.getForecastFromData;
            var celsius = ((fahrenheit - 32) * 0.56).toFixed(0);
            return celsius; // Calculation goes here.
        }
    }
});

Upvotes: 0

Views: 562

Answers (1)

AlvinJ
AlvinJ

Reputation: 271

From what I can see, you initially set the temperature to be in Fahrenheit.

// Temperature
$scope.temperatureNames = ['C', 'F'];
$scope.selectedTemperatureName = $scope.temperatureNames[1]; 

The issue happens here:

$scope.changedTemperatureTo = function(temperatureName) {
  // debugger;
  if (temperatureName == 'C') {
    $scope.forecastAll = weatherService.arrayToCelsius($scope.forecastAll);
  } else if (temperatureName == 'F') {
    /*
      You aren't doing anything to the forcastAll variable when the temperature
      is F
    */
    $scope.forecastAll;
  }
};

Nothing is happening when the temperatureName == 'F'. So it'll convert from Farenheight to Celcius, but then nothing happens when going back.

Hope this helps!

Upvotes: 1

Related Questions