javascript push not working in array inside object - javascript

As you can see in the code, i tried to dynamically create arrays inside an object, it doesn't have a problem when debugging, but when i tried to use push method in the array it throws an error. By the way this is in google app script.
Push function not found in the object [object Object]: TypeError. (line 32, file
var LoopQuestGuildAchievementReward = function (spread_sheet, master_name, is_update) {
initializeBase(this, MasterBase, [spread_sheet, master_name, is_update]);
this.guild_achievement_columns = new Object();
this.create_guild_achievement_columns = function () {
var guild_achievement_coloumn_names = ['ids', 'event_ids', 'range_starts', 'range_ends', 'incentive_ids'];
for (var i = 0; i < guild_achievement_coloumn_names.length; i++) {
if (!this.guild_achievement_columns[guild_achievement_coloumn_names[i]]) {
this.guild_achievement_columns[guild_achievement_coloumn_names[i]] = {};
};
};
};
};
LoopQuestGuildAchievementReward.prototype.setMaster = function(option) {
if (!option || !option.summary_values || !option.batch_reward_values) {
throw "Argument exception.";
};
var event_id = option.summary_values[8][0];
var incentive_values = option.batch_reward_values;
var incentive_master_id = Commons.getIncentiveId(1, event_id, 5);
var data_row_number = searchRowNumberWrittenLavelInColumn_(incentive_values, 1, "reach num") + 1;
var guild_achievement_last_id = Commons.getLatestId("loop_quest_guild_achievement_reward", "ja") + 1;
this.create_guild_achievement_columns();
while (data_row_number < incentive_values.length && incentive_values[data_row_number][1] != "") {
var reach_number = incentive_values[data_row_number][1];
Logger.log(this.guild_achievement_columns.ids);
this.guild_achievement_columns.ids.push(guild_achievement_last_id); // <- this where the error message points (line no. 32)
// this.guild_achievement_columns.event_ids.push(event_id);
// this.guild_achievement_columns.range_starts.push(reach_number);
// this.guild_achievement_columns.range_ends.push(reach_number - 1);
// this.guild_achievement_columns.incentive_ids.push(incentive_master_id);
guild_achievement_last_id++;
incentive_master_id++;
data_row_number++;
}
Logger.log(this.guild_achievement_columns);
};

After asking my superior he mention that curly braces refer to objects and brackets refer to array.
Object: this.guild_achievement_columns[guild_achievement_coloumn_names[i]] = {};
Array: this.guild_achievement_columns[guild_achievement_coloumn_names[i]] = [];

Related

Define map inside name space

Trying to define global map inside namespace and access that inside those namespace functions. but keep on getting Uncaught SyntaxError: Unexpected identifier. Appreciated If any one could guide me in defining global map inside namespace function and accessing.
var namespace = {
var mymap = new map();
cm: function () {
var childContainer = $("<div>");
namespace.myMap.set(cc, childContainer);
},
hm: function(ccm, data){
var cMenuItem = ccm.innerHTML;
for (var i = 0; i < data.c.length; ++i){
if ( cMenuItem === data.c[i]['l']){
namespace.Menus(data.c[i]);
namespace.myMap.get(cc);
}
}
}
};
Error comes in the first line var mymap = new map(); as Uncaught SyntaxError: Unexpected identifier
You are declaring a var inside an object. You cannot do that. You can only declare variables in a function.
What you did:
var namespace = {
var mymap = new map(); // <------ this line
cm: function () {
var childContainer = $("<div>");
namespace.myMap.set(cc, childContainer);
},
hm: function(ccm, data){
var cMenuItem = ccm.innerHTML;
for (var i = 0; i < data.c.length; ++i){
if ( cMenuItem === data.c[i]['l']){
namespace.Menus(data.c[i]);
namespace.myMap.get(cc);
}
}
}
};
What you should do:
var namespace = {
mymap: new map(); // <----- this line
cm: function () {
var childContainer = $("<div>");
namespace.myMap.set(cc, childContainer);
},
hm: function(ccm, data){
var cMenuItem = ccm.innerHTML;
for (var i = 0; i < data.c.length; ++i){
if ( cMenuItem === data.c[i]['l']){
namespace.Menus(data.c[i]);
namespace.myMap.get(cc);
}
}
}
};
Besides, map() is not Map(), as mentioned in comment.

Getting javascript undefined TypeError

Please help....Tried executing the below mentioned function but web console always shows
TypeError: xml.location.forecast[j] is undefined
I was able to print the values in alert but the code is not giving output to the browser because of this error. Tried initializing j in different locations and used different increment methods.How can i get pass this TypeError
Meteogram.prototype.parseYrData = function () {
var meteogram = this,xml = this.xml,pointStart;
if (!xml) {
return this.error();
}
var j;
$.each(xml.location.forecast, function (i,forecast) {
j= Number(i)+1;
var oldto = xml.location.forecast[j]["#attributes"].iso8601;
var mettemp=parseInt(xml.location.forecast[i]["#attributes"].temperature, 10);
var from = xml.location.forecast[i]["#attributes"].iso8601;
var to = xml.location.forecast[j]["#attributes"].iso8601;
from = from.replace(/-/g, '/').replace('T', ' ');
from = Date.parse(from);
to = to.replace(/-/g, '/').replace('T', ' ');
to = Date.parse(to);
if (to > pointStart + 4 * 24 * 36e5) {
return;
}
if (i === 0) {
meteogram.resolution = to - from;
}
meteogram.temperatures.push({
x: from,
y: mettemp,
to: to,
index: i
});
if (i === 0) {
pointStart = (from + to) / 2;
}
});
this.smoothLine(this.temperatures);
this.createChart();
};
You are trying to access the element after the last one. You can check if there is the element pointed by j before proceeding:
Meteogram.prototype.parseYrData = function () {
var meteogram = this,
xml = this.xml,
pointStart;
if (!xml) {
return this.error();
}
var i = 0;
var j;
$.each(xml.location.forecast, function (i, forecast) {
j = Number(i) + 1;
if (!xml.location.forecast[j]) return;
var from = xml.location.forecast[i]["#attributes"].iso8601;
var to = xml.location.forecast[j]["#attributes"].iso8601;
});
};

Filtering an array of Objects in javascript

I'm really new to JS, and I'm now stuck on a task, hope someone can guide me through it.
I have an Array of Objects, like this one:
var labels = [
// labels for pag 1
{pageID:1, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]},
// labels for pag 2
{pageID:2, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]}
]
What I am trying to do is write a function to return me an array of labels (Objects) for a specific page and a specific lang. By calling this function specifying pageID 1 and lang eng, I'm basically trying to build an array like this one:
var desideredArray = [
{labelID:0, text:'Txt1 Eng'},
{labelID:1, text:'Txt1 Eng'},
{labelID:2, text:'Txt2 Eng'}
]
Now, I'm trying to write the function to retrieve/build the new array:
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
// simpleLabelObject.text = ?????
results[i] = simpleLabelObject;
}
console.log (results);
};
...but how can I access the right value (the one corresponding the lang selected) in the content property?
You can use the same technique as the one used to keep the matching page: the filter method.
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var contentFilter = function(obj){ return obj.lang === lang};
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(contentFilter);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
console.log (desiredResults);
};
I didn't do bound checks because in your code you assumed there is always a matching element, but it would probably be wise to do it.
And if you want to avoid creating two closures each time the function is called, you can prototype an object for that:
var Filter = function(numPage, lang) {
this.numPage = numPage;
this.lang = lang;
};
Filter.prototype.filterPage = function(obj) {
return obj.pageID === this.numPage;
}
Filter.prototype.filterLang = function(obj) {
return obj.lang === this.lang;
}
Filter.prototype.filterLabels = function(labels) {
var result = labels.filter(this.filterPage, this);
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(this.filterLang, this);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
return desiredResults;
}
console.log(new Filter(1, "eng").filterLabels(labels));
Just filter again:
var getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function (obj) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i = 0; i < tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var lg = tempResult[i].content.filter(function (lg) {
return lg.lang == lang;
});
simpleLabelObject.text = lg[0].text;
desiredResults.push(simpleLabelObject);
}
console.log(desiredResults);
};
http://jsfiddle.net/9q5zF/
A rather 'safe' implementation for cases when pages have the same pageID and multiple contents with the same lang:
this.getLabelsForPageAndLang = function(numPage, lang) {
var result = [];
var pages = labels.filter(function( obj ) {
return obj.pageID === numPage;
});
for (var p = pages.length - 1; p >= 0; p--) {
var page = pages[p];
for(var i = page.labels.length - 1; i >= 0; i--) {
var labelId = page.labels[i].labelID;
for (var j = page.labels[i].content.length - 1; j >= 0; j--){
if (page.labels[i].content[j].lang === lang) {
result.push({labelID: labelId, test: page.labels[i].content[j].text});
}
}
}
}
console.log(result);
}
Fiddle: http://jsfiddle.net/6VQUm/

javascript array - accessing json type of objects

The code:
function getDummyDetails(){
var userDetailsMap = [];
userDetailsMap.push({key:'APPCODE', value:'41'});
userDetailsMap.push({key:'WORKERNUMBER', value:'1234567'});
userDetailsMap.push({key:'ACCOUNTID', value:'DEVELOP'});
userDetailsMap.push({key:'NAMEFIRST', value:'John'});
userDetailsMap.push({key:'NAMELAST', value:'Developer'});
return userDetailsMap;
}
function someOtherFunction () {
var userDetails = getDummyDetails();
document.getElementById("userName").innerHTML = "User Name: " + userDetails[3].value + ", " + userDetails[4].value;
}
Here, it works fine but I can not use the array index here like userDetails[3].value. I was trying to do something like this
userDetails["APPCODE"].value; // just a pseudo code
How can I index this array with that string values but not an integer?
You should create an object instead of an array. That way you'll be able to access it via its key:
function getDummyDetails() {
return {
'APPCODE':'41',
'WORKERNUMBER':'1234567',
'ACCOUNTID':'DEVELOP',
'NAMEFIRST':'John',
'NAMELAST':'Developer'
};
}
function someOtherFunction () {
var userDetails = getDummyDetails();
userDetails["APPCODE"] // 41 - use it however you want...
}
You need to create an object, not an array:
var userDetailsMap = {
APPCODE:41
}
var value = userDetailsMap["APPCODE"];//value now = 41
If you don't want to change your structure, you can iterate over your array:
for (var i = 0, len = userDetailsMap.length; i < len; i++) {
if (userDetailsMap[i].key == 'APPCODE') {
var val = userDetailsMap[i].value;
// do something with the value here
}
}

passing array to Constructor function and keep it public

here is my code :
var BoxUtility = function() {
var boxList = Array.prototype.pop.apply(arguments);
};
Object.defineProperties(BoxUtility, {
totalArea: {
value: function(){
var x = 0;
for(var i = 0, len = boxList.length; i <= len - 1; i++){
x = x + boxList[i].area;
};
return x;
}
}
});
I'm trying to achieve this syntax for my Code :
var boxArray = [box01, box02, box03];
box are objects, box01.area => boxes have area property
var newElement = new BoxUtility(boxArray);
alert(newElement.totalArea);
I WANT TO SEE THE RESULT AS I EXPECT but I think boxList is in another scope
How can I reach it in defineProperties
You have to assign the value to a property of this in your constructor.
var BoxUtility = function() {
// this.boxList
this.boxList = Array.prototype.pop.apply(arguments);
};
// instance methods go on the prototype of the constructor
Object.defineProperties(BoxUtility.prototype, {
totalArea: {
// use get, instead of value, to execute this function when
// we access the property.
get: function(){
var x = 0;
// this.boxList
for(var i = 0, len = this.boxList.length; i <= len - 1; i++){
x = x + this.boxList[i].area;
};
return x;
}
}
});
var boxUtil = new BoxUtility([{area:123}, {area:456}]);
console.log(boxUtil.totalArea); // 579
Variable scope is always at the function level. So you declared a local variable that is only usable inside your constructor function. But every time you call the constructor function you get a new object (this). You add properties to this in order to have those properties accessible in your instance methods on the prototype.
this works
var BoxUtility = function() {
this.boxList = Array.prototype.pop.apply(arguments);
Object.defineProperties(this, {
totalArea: {
get: function(){
var x = 0;
for(var i = 0, len = this.boxList.length; i <= len - 1; i++){
x = x + this.boxList[i].area;
};
return x;
}
}
});};
var y = new BoxUtility(boxArray);
alert(y.totalArea)
This is simple way to pass array as argument in constructer and declare function prototype for public access.
function BoxUtility(boxArray) {
this.boxArray = boxArray;
this.len = boxArray.length;
}
Color.prototype.getAverage = function () {
var sum = 0;
for(let i = 0;i<this.len;i++){
sum+=this.boxArray[i];
}
return parseInt(sum);
};
var red = new BoxUtility(boxArray);
alert(red.getAverage());

Categories

Resources