Reputation: 83
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);
}
Upvotes: 7
Views: 2047
Reputation: 22071
c.name
is undefined for some item in your listData
. Checkout JSON which you receive from server, not faked one.
NOTE: $http.get is asynchronous.
Putting self.myFunc = ...
into success handler of $http.get suppose to give correct behaviour. You can take a look on Understanding Asynchronous Code in Layman's terms to see how async works.
Good Luck ! :)
Upvotes: 0
Reputation: 10803
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>
Upvotes: 1
Reputation: 5812
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);
}
Upvotes: 1
Reputation: 405
Just by looking at your code. It looks like "c.name" is undefined. May be you can print that variable out and see what's in it
Upvotes: 0