Oops! The angular app encountered an error: TypeError - it cannot read property '0' of undefined. Time to debug

Having difficulty grasping the source of an error, as the html side is able to read list[3].main.temp without any issues. However, in the second loop of the generateList function, I encounter an error specifically on $scope.list[i].main.temp, which throws:

TypeError: Cannot read property '0' of undefined =\

This code is designed to select a random sample of 10 cities out of a list of 30 and display their current temperatures.

var WeatherApp = angular.module("WeatherApp", ["ngRoute", "ngResource"]).
config(function ($routeProvider) {
    $routeProvider.
        when('/', { controller: ListCtrl, templateUrl: 'list.html' }).
        otherwise({ redirectTo: '/' });
});

WeatherApp.factory('City', function ($resource) {
return $resource('/api/City/:id', { id: '@id' }, {update: { method: 'PUT'}});
 });

var ListCtrl = function ($scope, $location, City, $http) {
$scope.city = City.query();

$scope.units = 'metric';
$scope.appId = '';
$scope.displayNum = 10;
$scope.display = [];
$scope.display.temp = [];

$scope.generateList = function () {
    $scope.exp = City.query(function (exp) {
        shuffle(exp);
        $scope.cityIdAr = [];
        for (var i = 0; i < $scope.displayNum; ++i) {
            $scope.display.push($scope.exp[i]);
            $scope.cityIdAr.push($scope.exp[i].CityId);
        };
        $scope.cityId = $scope.cityIdAr.join();
        $scope.getWeather();
        for (var i = 0; i < $scope.displayNum; ++i) {
            $scope.display.temp.push($scope.list[i].main.temp);
        };
    });
};

function shuffle(ob) {
    for (var j, x, i = ob.length; i; j = Math.floor(Math.random() * i), x = ob[--i], ob[i] = ob[j], ob[j] = x);
    return ob;
};

$scope.getWeather = function () {
    var url = 'http://api.openweathermap.org/data/2.5/group';
    $http.jsonp(url, {
        params: {
            id: $scope.cityId,
            APPID: $scope.appId,
            units: $scope.units,
            callback : 'JSON_CALLBACK'
        }
    }).success(function (data, status, headers, config) {
        $scope.data = data;
        $scope.list = data.list;
        });
};


$scope.generateList();
};

Answer №1

One issue that may arise is the potential for $scope.list to be undefined until the callback is executed. To address this, you could modify $scope.getWeather to return a promise and resolve it within $scope.generateList. This way, the data retrieval process triggers the for loop only when the data is available (inside the callback).

To implement this change, update $scope.getWeather:

$scope.getWeather = function () {
  ...
  return $http.jsonp(...)
}

Then, adjust $scope.generateList:

...
$scope.getWeather().success(function(data, status, headers, config) {
  $scope.data = data;
  $scope.list = data.list;
  for (var i = 0; i < $scope.displayNum; ++i) {
    $scope.display.temp.push($scope.list[i].main.temp);
  };
}

Implement similar changes as outlined above.

Answer №2

Use a different variable instead of $scope.display as it conflicts with List

var WeatherApplication = angular.module("WeatherApp", ["ngRoute", "ngResource"]).
config(function ($routeProvider) {
    $routeProvider.
        when('/', { controller: ListController, templateUrl: 'list.html' }).
        otherwise({ redirectTo: '/' });
});

WeatherApp.factory('City', function ($resource) {
return $resource('/api/City/:id', { id: '@id' }, {update: { method: 'PUT'}});
 });

var ListController = function ($scope, $location, City, $http) {
$scope.cityList = City.query();

$scope.units = 'metric';
$scope.appId = '';
$scope.numOfDisplay = 10;
$scope.displayData = [];
$scope.tempData = [];

$scope.generateList = function () {
    $scope.explore = City.query(function (explore) {
        shuffle(explore);
        $scope.cityIdArray = [];
        for (var i = 0; i < $scope.numOfDisplay; ++i) {
            $scope.displayData.push($scope.explore[i]);
            $scope.cityIdArray.push($scope.explore[i].CityId);
        };
        $scope.cityIds = $scope.cityIdArray.join();
        $scope.getWeather();
        for (var i = 0; i < $scope.numOfDisplay; ++i) {
            $scope.tempData.push($scope.list[i].main.temp);
        };
    });
};

function shuffle(obj) {
    for (var j, x, i = obj.length; i; j = Math.floor(Math.random() * i), x = obj[--i], obj[i] = obj[j], obj[j] = x);
    return obj;
};

$scope.getWeather = function () {
    var url = 'http://api.openweathermap.org/data/2.5/group';
    $http.jsonp(url, {
        params: {
            id: $scope.cityIds,
            APPID: $scope.appId,
            units: $scope.units,
            callback : 'JSON_CALLBACK'
        }
    }).success(function (data, status, headers, config) {
        $scope.dataResponse = data;
        $scope.list = data.list;
        });
};


$scope.generateList();
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Array map function is not displaying the list within a React component that is based on a Class

I am having trouble displaying a list of food items in my Parent component FoodBox.js and its child component FoodItems.js. I am using the map() method, but the <ul> element is showing up empty. Here is my code for FoodBox.js const FOOD_ITEMS = [ { ...

Issues with executing javascript callback functions within Node.js and express

/* Access home page */ router.get('/home/', function(req, res, next) { var code = req.query.code; req.SC.authorize(code, function(err, accessToken) { if ( err ) { throw err; } else { req.session.oauth_token = accessToken ...

What is the best way to automatically set today's date as the default in a datepicker using jQuery

Currently utilizing the jQuery datepicker from (http://keith-wood.name/datepick.html), I am seeking to customize the calendar to display a specific date that I select as today's date, rather than automatically defaulting to the system date. Is there a ...

Incorporate Thymeleaf's HTML using the powerful JavaScript framework, jQuery

I am facing an issue where the Thymeleaf rendered HTML code is not being displayed by the Browser when I try to insert it using JavaScript. $('<span [[$ th:text#{some.property.key}]] id="counter" class="UI-modern"> </ ...

Is it possible to upload multiple files using JavaScript?

My JavaScript project can be found on GitHub. You can check out a live demo of the project here. The main goal for my HTML Button with id='Multiple-Files' is to enable users to upload multiple files, have them displayed in the console, and then ...

Can you explain the contrast between uploading files with FileReader versus FormData?

When it comes to uploading files using Ajax (XHR2), there are two different approaches available. The first method involves reading the file content as an array buffer or a binary string and then streaming it using the XHR send method, like demonstrated he ...

jQuery ajaxSetup: handling error retries for ajax calls is not possible

When using $.ajaxSetup(), I am faced with the challenge of making an AJAX request after refreshing a valid token in case the previous token has expired. The issue arises when attempting to execute $.ajax(this) within the error callback. $.ajax({ url: ...

How to test an AngularJS controller that utilizes a service which returns a promise

I am currently creating unit tests for my components. After conducting thorough research, I have come to the realization that testing components that rely on services can be quite cumbersome and may require some messy work. I am feeling unsure about the ...

When I include scroll-snap-type: y; in the body tag, the scroll-snapping feature does not function properly

Hey there! I've been trying to implement scroll-snapping on my project but unfortunately, I couldn't get it to work. I tested it out on both Chrome and Firefox, but no luck so far. Here's the code snippet I've been working with, would a ...

Storing Data Property Value from an Item in Rendered List Using Vue: A Quick Guide

I'm currently working on implementing a follow button for list items in Vue. My approach involves extracting the value of a specific property from a list item and storing it in the data object. Then, I plan to utilize this value within a method to app ...

Tips on sorting a FileList object selected by a directory picker in JavaScript/TypeScript

I need to filter or eliminate certain files from a FileList object that I obtained from a directory chooser. <input type="file" accept="image/*" webkitdirectory directory multiple> Within my .ts file: public fileChangeListener($event: any) { let ...

Function that is triggered repeatedly when modifying the state within it

Within my render method, I am calling a handlePageClick function like this: onPageChange={this.handlePageClick} The function itself looks like this: handlePageClick = data => { this.setState({ circleloading: true }); let names = ...

Tips on how to choose all elements that do not include a specific value or group of values in cypress

Here's my situation: selector: ".list > div" const velue = [6, 9, 21] Each div contains a different value. I want to remove elements that contain a specific value, then select the first remaining element and click on it. It should look ...

Using the Google Chrome console, execute a command on each page within a specified website

While browsing a website, I noticed a bug that required me to manually run a JavaScript function each time I navigated to a different page in order for the site to work smoothly. Is there a way to automate this process upon page load? I am using Google C ...

What is the Ideal Location for Storing the JSON file within an Angular Project?

I am trying to access the JSON file I have created, but encountering an issue with the source code that is reading the JSON file located in the node_modules directory. Despite placing the JSON file in a shared directory (at the same level as src), I keep r ...

Is it possible to build an asp.net chat application using RegisterWaitForSingleObject

Successfully implemented server response in chunks to a client while learning to create my own chat system. I've created two versions - one works, but the other does not. Here is the code for the working version: static EventWaitHandle _waitHandl ...

Retrieving information from Prismic API using React Hooks

I'm having trouble querying data from the Prismic headless CMS API using React Hooks. Even though I know the data is being passed down correctly, the prismic API is returning null when I try to access it with React Hooks. Here is my current component ...

Checking for "in array" using AngularJS expressions

I need a clean and efficient way to achieve something like the following: <span x-ng-show="stuff && stuff.id in [1,2,5]">{{stuff.name}}</span> <span x-ng-show="stuff && stuff.id in [3,4,6]">{{stuff.fullName}}</span> ...

Selecting a single checkbox automatically selects all other checkboxes

Is there a way to automatically check all other checkboxes if one checkbox is checked? Here's the code snippet I have: <tr> <td class="small"><asp:CheckBox ID="chkReportModuleName" runat="server" name="report"></asp:CheckBox& ...

Why do I keep getting errors in TypeScript when I manipulate DOM elements using getElementsByClassName(), even though my application still functions properly?

I am dealing with an Angular2 application. Unfortunately, I have had to resort to using the following code within a component method (I know it's not ideal, but...): let confirmWindowDOM = document.getElementsByClassName('modal')[0]; confir ...