Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot read property 'toLowerCase' of undefined (Angularjs/JavaScript/Json)

I'm building Angular/Express app, I load data with controller and try to work with data in a function but I get error in console

Cannot read property 'toLowerCase' of undefined

When I manually write JSON data it works just fine. Anyone had this error and why is it happening?

Edit: Also I want function to work on click, when I want it not when it's loaded, also I use data from listData in view so I know it's loaded

Controller

var self = this; 
self.listData = [];

var self = this; 
self.listData = [];

$http.get('/myList')
.success(function (data) {
    self.listData = data;
    console.log(data);
})
.error(function (data) {
    console.log('Error: ' + data);
});

self.myFunc = function(){
    var map = self.listData.reduce(function (p, c) {
        p.set(c.name.toLowerCase(), c.surname);
        return p;
    }, new Map());

    console.log(...map);
}
like image 848
Absolute Beginer Avatar asked Aug 05 '16 09:08

Absolute Beginer


2 Answers

HTTP.GET is an asynchronous function

You could call your function which turns the data to lowercase in the .success of your http.get. That way you know that the data has arrived. Now you might be executing this function a bit too early which means that you do not yet have the data in your list.

If you try to run the toLowerCase() on your data, before you actually retrieved the data you will get this error. That is one of the things you learn to deal with when working with web requests.

For example writing your code like this would work.

   $http.get('/myList')
           .success(function (data) {
                self.listData = data;
                myFunc(listData);
                console.log(data);
           })
           .error(function (data) {
                console.log('Error: ' + data);
           });

 }

 function myFunc(){

    var map = self.listData.reduce(function (p, c) {
                p.set(c.name.toLowerCase(), c.surname);
                return p;
           }, new Map());

           console.log(...map);

 }
like image 134
Dylan Meeus Avatar answered Nov 16 '22 16:11

Dylan Meeus


Here is your updated code works on click of an element:

jQuery("#a-div-to-click").on("click", function() {
    var self = this; 
    self.listData = [];
    $http.get('/myList').success(function (data) {
            self.listData = data;
            console.log(data);
            self.myFunc();
       }).error(function (data) {
            console.log('Error: ' + data);
       });
    }
    self.myFunc = function(){
        var map = self.listData.reduce(function (p, c) {
                p.set(c.name.toLowerCase(), c.surname);
                return p;
        }, new Map());

        console.log(map);
    }

});

V2) The data is loaded at "onload" phase and the process done at "onclick" phase:

app.controller('yourController', function ($scope, $http) {

    $scope.fetchData = funcion(onSuccess) {
        $http.get('/myList').success(function (data) {
                $scope.aDivlistData = data;
                console.log(data);
                if (onSuccess != null) {
                    onSuccess();
                }
           }).error(function (data) {
                console.log('Error: ' + data);
           });
        }
    }();

    $scope.onADivClicked = function() {
        if ($scope.aDivlistData == null) {
            $scope.fetchData($scope.populateMap);
        } else {
            $scope.populateMap();
        }

    };

    $scope.populateMap = function() {
        var map = $scope.aDivlistData.reduce(function (p, c) {
                p.set(c.name.toLowerCase(), c.surname);
                return p;
        }, new Map());

        console.log(map);
    }
}
//html part:
//<div id="a-div-to-click" ng-click="onADivClicked()">A Div</a>
like image 40
Bahadir Tasdemir Avatar answered Nov 16 '22 15:11

Bahadir Tasdemir