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

Normalization of Firebase Database

Recently, I developed a Tricycle Patrol app designed to address the prevalent issue of reckless tricycle drivers in our city. Users can log in and submit reports through a form that includes fields such as: - created_at - description - lat - lng - plateNu ...

Unraveling a date field from JSON with AngularJS filtering

Extracting data from JSON file shows /Date(1435837792000+0000)/ How can I format the date to appear as Oct 29, 2010 9:10:23 AM? ...

When a user chooses an item, the ui-select dropdown appears hidden behind additional fields on the screen

In my AngularJS application, I am utilizing ui-select within a table that repeats rows using ng-repeat. The following code snippet displays how ui-select is implemented: <ui-select name="{{'selProperty' + $index}}" ng-model="thing.property" ...

Splitting the div into two columns

I've encountered various solutions to this issue, but when I integrate an Angular2 component inside the divs, it fails to function properly. Here is my progress so far: https://i.stack.imgur.com/qJ8a9.jpg Code: <div id="container"> <div ...

The HTML div captured with html2canvas is incomplete

I am currently developing a meme editor website utilizing the html2canvas library available at Below is the HTML code for the div I aim to capture: <div class="container"> <div id="theUserMeme"> <div class=& ...

Does the resolve function within a Promise executor support async operations?

I'm trying to wrap my head around the following code: function myPromiseFunc() { return new Promise((resolve) => { resolve(Promise.resolve(123)); }); } We all know that the Promise.resolve method immediately resolves a Promise with a plain ...

What is the number of steps jQuery animates in?

Exploring my creative side, I decided to create my own custom animate function. Struggling to achieve a seamless animation effect, unlike the smooth transitions produced by jQuery. I'm curious about the formula they utilize to determine the ideal num ...

Building a dynamic URL in ReactJS from scratch

const selectedFilters = { category: "", mealtype: "lunch", cuisinetype: "Italian", dishType: "Pasta" } const apiUrl = `https://api.edamam.com/api/recipes/v2?type=public&q=${query}&app_id=${app_id}&app_key=${app_key}`; User ...

Activate the b-form-file function by selecting the b-button

Working with BootstrapVue, I am trying to trigger my b-form-file after clicking on a b-button for style reasons. Additionally, I want the b-form-file to be hidden so it is not visible. I attempted the following approach, but it did not work for me: <b- ...

The usage of nextTick in Vue.js and its role in updating components

Although I am a beginner with vue.js and have a basic understanding of it, I came across a sample code utilizing nextTick() today. Trying to comprehend its purpose led me to explore the documentation, which ended up complicating things further and leavin ...

Is there a library available for generating QR codes on the server side and saving them directly to a database

My Goal: I am looking to create a functionality where, upon clicking "Generate QRCode," JavaScript will utilize the local machine's datetime to generate an md5 hash in the MMDDYYHHMMSS format. I then want this hash to be sent to the server to produce ...

Error encountered in Next.js Webviewer during build process: "Reference Error - window is not defined"

Currently, I am in the process of developing a website that includes a PDF viewer within a dynamically imported page. When I run the code locally, everything works without any issues. However, when I execute the "npm run build" command, I encounter the fol ...

Incorporate JSON information into HTML dropdown menu using Google API

I'm finding it difficult with this task. Below is a list that needs the name and address inserted into the dropdown menu from the JSON file. <div class="dropdown-list"> <div class="list-container"> <ul class="list" ...

``When you click, the image vanishes into thin

Could you please explain why the image disappears once I close the lightbox? Access with password: chough ...

What is the best way to search for a specific item in Express.js?

I recently got the Leaderboard API issue fixed, but now I'm encountering a new problem with express Querying. Specifically, I'm attempting to search for a specific Discord ID using quick.db as my database. I've included an excerpt of my expr ...

Content within a popup or modal in AngularJS

Currently, I am in the midst of my AngularJS learning journey where I am actively engaging with the material to improve my skills. However, there is one particular issue that has been puzzling me and eluding any clear solution. Here's what I'm t ...

Exploring the power of jQuery closures and handling events like mouseover and mouseout

I'm currently grappling with the concept of utilizing closures in conjunction with jQuery event functions. The challenge I am facing involves creating rounded shapes on the screen that stop and fade when hovered over, then resume fading when the mous ...

Tips for iterating through the properties of every object within a Knockout observableArray and dynamically generating a table

My observableArray is dynamically populated with SQL data, resulting in varying columns each time. I am trying to present the SQL results in an HTML table but facing issues with the code below. This is the desired output format... var viewModel = func ...

AngularJS and the JavaScript programming language

Struggling with opening an Excel sheet by clicking on a button? I've written the code, but encountering issues. function openFile(strFilePath) { var objExcel; //Create EXCEL object objExcel = new ActiveXObject("Excel.Applicati ...

Why is it necessary to use 'this.' to reference a function inside a Component in React?

class First extends React.Component{ handleClick(){ alert('handle click'); } render(){ return <div> <button onClick={this.handleClick}>click</button> </div>; } } Explo ...