Javascript: Object properties undefined (very specific case) [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have a function which is a loop by itself and in this loop I am creating an object. But when after the loop I'm trying to access the object properties, I get an response of undefined.
When I try to just console.log the object itself, I get it. The problem is with properties.
I would be grateful, if someone could help me. I did a good research, but didn't manage to find the solution. My case is very strange. Everything is good except the properties. I need the help of senior developers.
Here is the code.
var countMap = {};
var counter = 0;
$('#share_table_body').find('.js-post').each(function () {
var totalCount = 0;
$(this).find('.js-social').each(function () {
var $this = $(this);
var socialType = $(this).data('social-type');
var url = $this.closest('.js-post').data('url');
getShareStatus(url, socialType)
.then(function (shareCount) {
$this.text(shareCount);
if (!countMap[socialType]) {
countMap[socialType] = 0;
}
if (!countMap['total']) {
countMap['total'] = 0;
}
countMap[socialType] += shareCount;
totalCount += shareCount;
countMap['total'] += shareCount;
$this.siblings('.js-total').text(totalCount);
})
.fail(function (err) {
$('.error-notice').removeClass('hidden');
$this.css('color', 'red').text('!');
});
});
counter++;
});
if (counter == $('#share_table_body').find('.js-post').length) {
console.log(countMap);
$('.total-facebook').text(countMap['facebook']);
}

Are you returning anything from your function? Specifically...
return countMap;

Related

JavaScript returning undefined when it's actually defined [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
My console.log shows the right values, but I can't access my properties!
var subMenus = [], mainMenu = {};
$.getJSON("js/menu.js", function(data){
var menuJsonish = data.MenuEXTERNAL;
//first turn this into an actual array instead of this dumb, non Json stuff
$.each(menuJsonish, function(e) {
var name = e.valueOf();
var eachMenu = [];
if (e != "MenuSettings") { //skip MenuSettings
$.each(menuJsonish[name], function(element) {
var menuArray = [];
$.each(menuJsonish[name][element], function(item) {
var currentItem = menuJsonish[name][element][item];
var k = currentItem[0].valueOf();;
var v = currentItem[1].valueOf();
if (e == 'Menu1') {
eval("mainMenu."+k+" = '"+v+"'");
} else {
eachMenu[k] = v;
}
});
});
if (e != 'Menu1') {
subMenus[e] = eachMenu;
}
}
});
});
// this one returns undefined...
console.log(mainMenu.Menu1);
// yet this one returns all the correct data as shown in the screenshot
console.log(mainMenu);
I don't understand what is going on here. Shouldn't a value be a value? And more importantly, how do I get my data?
I don't think it's necessary to post the entire "JSON" file (which I did NOT create, but I have to work with), but I will post screenshot #2 which shows what it looks like, and why I have to load it like this.

How can I call the second sequential promise design pattern method in a loop in angularjs? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
New to angularjs and trying out the promise pattern for the first time -
I have a service utility inside which I have this method -
this.getData= function(url){
var defer = $q.defer();
$http({method: 'GET', url: url}).
success(function(data, status){
defer.resolve(data);
})
.error(function(data, status) {
defer.reject(status);
});
return defer.promise;
};
Now inside my controller, I am calling a method called A()
var A = function () {
$scope.myobjectArray = [];
return utility.getData("some url").then(funciton(data)
{
for (i = 0; i < data.length; i++) {
$scope.myobjectArray.push(data[i].attribute1, new Array());
}
}
).
then(function () {
return getTheSecondAttributeArray();
}).catch(function (status) {
//display error
});
};
var getTheSecondAttributeArray = function () {
for (i = 0; i < $scope.myObjectArray.length; i++) {
var secondAttributeArray = [];
var currentType = $scope.myObjectArray[i];
utility.getData("some url").then(function (response) {
for (j = 0; j < response.length; j++) {
//some response manipulation
secondAttributeArray.push(response[j].text);
}
currentType.secondAttribute = secondAttributeArray;
}).catch(function () {//catch error, display message
})
}
}
However, it looks like that the last element of the $scope.myobjectArray (n-1th element) is only getting populated. Also, the secondAttributeArray that this last element contains is a concatenated array of all secondAttributes for all objects of the $scope.myobjectArray.
Cannot figure out what can I change here.
EDIT:
When I tried accessing $scope.myObjectArray[j] inside the 'then' function, it said $scope.myObjectArray[j] was undefined. --> And so I created a currentType variable and assigned $scope.myObjectArray[j] to it and that was easily accessible inside the 'then' function. Weird!
Also, I see that only the last object of the $scope.myObjectArray gets values and not the rest. The rest of the objects in the array are empty
Any help is appreciated.
var myObject = function(firstattribute, secondAttribute){
this.firstattribute = firstattribute;
this.secondAttribute = secondAttribute;
}
The explanation here by Beehive (Angularjs $q.all) is something that I am facing. I only get the last loop's data.
The issue is all in function closures. When the get data returns, your currentType is the last one because the for j loop ended already. So what you need to do is move the code starting from utility.getData to a separate method passing the parameters of the currentType and the seccondAttributeArray so the closure will contain them as parameters of the function and not change them as the for j loop progresses.
for (i = 0; i < $scope.myObjectArray.length; i++) {
var secondAttributeArray = [];
var currentType = $scope.myObjectArray[i];
fillSecondAttributeArray($scope, secondAttributeArray, currentType);
}

Store JSON object in a global accessible array [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I'm trying to build a function that stores an array of JS objects in a global scope (I want to access this from an external Prototype function). However, when I try to return the 'build' array, the array is undefined (this is probally because I need a proper callback function).
How can I achieve this in a proper way?
function getMyJson(url){
var request = $.getJSON(url);
var items = [];
request.done(function(response) {
for (var key in response) {
if (response.hasOwnProperty(key)) {
var object = {
name: response[key].name,
id: response[key].id
}
items.push(object);
}
}
});
return items; // This returns 'undefined', probally because the for loop is still running
}
var data = getMyJson('data.json');
console.log(data); // undefined
Thanks in advance
As others have mentioned, callbacks are the way to go.
function getMyJson(url, callback){
var request = $.getJSON(url);
var items = [];
request.done(function(response) {
for (var key in response) {
if (response.hasOwnProperty(key)) {
var object = {
name: response[key].name,
id: response[key].id
}
items.push(object);
}
}
callback(items);
});
}
var data = getMyJson('data.json', function(items){
//items will be defined here.
});

issue in accessing object javascript getter [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
Closed 8 years ago.
I am writing getter and setters dynamically. my code is buggy. I need help in correcting it.
Portion of my code looks like following:
var a = {};
var myArray = ["abc", "xyz", "bbb"];
for (var i = 0; i < myArray.length: i++) {
var tempVar = myArray[i];
Object.defineProperty(this, tempVar, {
get: function () {
var ret = $.extend(true, {}, a[tempVar]);
return ret;
},
set: function (intObj) {
a[intObj.type] = intObj;
}
});
}
The problem of mine is there in get function I want to access value of tempVar but I am not able to access it.
While defining it is not even going in get function.
And while using it is going in get function but the tempVar will be last value of array only.
If some body can guide me in this. It would be great.
Yes that link helped. Thanks. So my code will now look like following. This is a basic concept but always run away from closures. Today learnt! Thanks.
var a = {};
var myArray = ["abc", "xyz", "bbb"];
for (var i = 0; i < myArray.length: i++) {
var tempVar = myArray[i];
Object.defineProperty(this, tempVar, {
get: function (newTemp) {
return function(){
var ret = $.extend(true, {}, a[newTemp]);
return ret;
}
}(tempVar),
set: function (intObj) {
a[intObj.type] = intObj;
}
});
}

How do I use a value outside of its function in JavaScript? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I have a function that calls a JSON string from another URL. The JSON is coming through fine and behaving as I want it to. The variable 'procode' is what I want to use outside the function, but I dont know how to pass the value of 'procode' up and out of the function completely, so I can use it on a global scale.
function(){
$.get('http://url-here/api/product', function(data) {
var rawcode = JSON.parse(data);
var procode = '"products":' + rawcode;
}, 'text');
}
Thanks in advance for any help :)
you need to set global variable to access it outside.Something like this:
var rawcode="";
var procode="";
function(){
$.get('http://url-here/api/product', function(data) {
rawcode = JSON.parse(data);
procode = '"products":' + rawcode;
}, 'text');
}
window.procode="";
var myFunction = function(){
var ajaxCall = $.get('http://url-here/api/product', function(data) {
var rawcode = JSON.parse(data);
window.procode= '"products":' + rawcode;
}, 'text');
$.when(ajaxCall).done(function(){
alert(window.procode);
});
};

Categories