Array format showing as object - javascript

hope you are doing well. I have faced an issue. I'm creating a dynamic array but when I console that variable and check typeOf of this variable it showing an object instead of an array. Also when I access a specific element of that variable it's showing undefined. Let me know how can I resolve this issue. you can check I have declared a global variable name of test and push data in it. it should return an array because I'm pushing it in the array. But showing object.
$(document).ready(async function(){
await load_pre_data(true);
});
let pre_data= [];
let count = 1;
var test = [];
let ws = new WebSocket('wss://ws.binaryws.com/websockets/v3?app_id=1089');
async function load_pre_data() {
ws.onopen = function (evt) {
ws.send(JSON.stringify({
ticks_history: 'frxAUDJPY',
adjust_start_time: 1,
count: 5,
end: "latest",
start: 1,
style: "ticks"
}));
};
ws.onmessage = function (msg) {
let response = JSON.parse(msg.data);
let loop;
for (loop = 0; loop <= response.history.prices.length; loop++) {
test.push(1);
}
}
console.log(test);
console.log(typeof (test));
}

In Javascript every array is the type of an object and for your typechecking you can use "Array.isArray(test)".
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
You can read about isArray() method here

Related

how to access objects that are returned from a function

New to javascript and learning about objects on freeCodeCamp. I have the function below that returns an object. I would like to be able to access totalOutboxes which holds an integer I get back outside of the function. I would like to do something like this
myTotal = result.totalOutboxes
where the variable myTotal will hold an integer that I get back. For example, it will hold 10. How can I go about doing this? A steer in the right direction would be great!
const getTotalResponses = () => {
const result = {
// This holds actual total outboxes
totalOutboxes,
conversations
}
return result;
};
Obtain the retuned object by assigning it to a variable and get the totalOutboxes property:
let totalOutboxes = 10,
conversations = 99;
const getTotalResponses = () => {
const result = {
totalOutboxes,
conversations
}
return result;
};
const myObject = getTotalResponses();
console.log(myObject.totalOutboxes);

Change value of dynamically added js object

I have an array with some predefined data
var data = [
{amount:20, speed:100},
{amount:40, speed:50}
];
I am then adding data to the above array
function addMore() {
data = appendObjTo(data, {amount: 1500,speed:100});
}
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
The data is being added fine, but for some reason, i am unable to change the value of the new data
function runData() {
perSec = 0;
$.each(data, function( key, value ) {
perSecCalc = Math.round(value.speed/60);
perSec += perSecCalc;
// Below line works only for predefined objects, but not objects from "addMore()"
data[key].amount = value.amount-perSec;
});
setTimeout(function() {
runData();
},1000);
}
While the predefined object in "var data" is being changed, the dynamically added data from "addMore" does not change.
How come the new data is not changing ?
Update:
See this fiddle
You are using Object.freeze in your appendObjTo function. The definition of Object.freeze - Object.freeze().
Since the frozenObj is created using Object.freeze(), the values are not allowed to change. Also, you are not getting any error on console. JS doesn't show error w/o strict mode enabled. I have modified the fiddle to include strict mode, and you can see that it throws and error when you do data[key].amount = value.amount-perSec;. I have also attached a fiddle to play with the Object.freeze() method, and you can experiment by yourself.
Modified fiddle
JS
(function () {
"use strict";
var data = [
{amount:20, speed:100}
];
function runData() {
var perSec = 0;
$.each(data, function( key, value ) {
var perSecCalc = Math.round(value.speed/60);
perSec += perSecCalc;
// Below line works only for predefined objects, but not objects from "addMore()"
data[key].amount = value.amount-perSec;
$('#test').prepend(data[key].amount+'<br>');
});
setTimeout(function() {
runData();
},1000);
}
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
function addMore() {
data = appendObjTo(data, {amount: 1500,speed:100});
}
setTimeout(function() { addMore(); },1500);
runData();
})();
Object.freeze fiddle
var arr = [10, 20, 30];
console.log(arr);
arr = Object.freeze(arr.concat([40, 50]));
console.log(arr);
arr[3] = 80;
console.log(arr); // doesn't change
// arr.push(60); // error, cannot add property 5, object is not extensible
arr = Object.freeze(arr.concat([{ x: 100 }]));
console.log(arr);
arr[5].x = 200;
console.log(arr); // changes, as Object.freeze only locks the first level values.

.map() unable to access Object's this.function

Thanks in advance for any responses:
I don't think this is a duplicate: I reviewed that article in the first comment, that is just a general breakdown of objects and using "this" within javascript.
My other this.function's perform just fine, so I at least have the basics of JS Obj's figured out.
This issue is related to using .map() with a this.function within a constructed object.
The following Google Appscript code uses .map() to update a string in a 2d array. [[string, int],[string, int]]
For some reason, when using .map() it is am unable to access the function "this.removeLeadingZero". If that same function is placed outside of the OBJ it can be called and everything works just fine. For some reason the system claims row[0] is an [object, Object] but when I typeof(row[0]) it returns "string" as it should.
Error: TypeError: Cannot find function removeLeadingZero in object [object Object]. (line 106, file "DEEP UPC MATCH")
Is there any issue using this.function's with .map() inside an object or am I using an incorrect syntax?
function test2DMapping(){
var tool = new WorkingMappingExample()
var boot = tool.arrayBuild();
Logger.log(boot)
}
function WorkingMappingExample(){
this.arr= [["01234", 100],["401234", 101],["012340", 13],["01234", 0422141],["01234", 2],["12340",3],["01234", 1],["01234", 2],["12340",3],["01234", 1],["01234", 2],["12340",3],["01234", 1],["01234", 2],["12340",3]];
//mapping appears faster that normal iterations
this.arrayBuild = function(){
var newArray1 =
this.arr.map( function( row ) {
**var mUPC = removeLeadingZero2(row[0])** //working
**var mUPC = this.removeLeadingZero(row[0])** // not working
var index = row[1]
Logger.log(mUPC + " " + index)
row = [mUPC, index]
return row
} )
return newArray1;
};
}; //end of OBJ
//THE NEXT 2 FUNCTIONS ARE WORKING OUTSIDE OF THE OBJECT
function removeLeadingZero2(upc){
try {
if (typeof(upc[0]) == "string"){
return upc.replace(/^0+/, '')
} else {
var stringer = upc.toString();
return stringer.replace(/^0+/, '')
}
} catch (err) {
Logger.log(err);
return upc;
}
}
function trimFirstTwoLastOne (upc) {
try {
return upc.substring(2, upc.length - 1); //takes off the first 2 #'s off and the last 1 #'s
} catch (err) {
Logger.log(err);
return upc;
}
}
Inside the function that you pass to map, this doesn't refer to what you think it does. The mapping function has its own this, which refers to window, normally:
var newArray1 = this.arr.map(function(row) {
// this === window
var mUPC = this.removeLeadingZero(row[0]);
var index = row[1];
Logger.log(mUPC + " " + index);
return [mUPC, index];
});
You have four options:
Array#map takes a thisArg which you can use to tell map what the this object in the function should be:
var newArray1 = this.arr.map(function(row) {
// this === (outer this)
var mUPC = this.removeLeadingZero(row[0]);
// ...
}, this); // pass a thisArg
Manually bind the function:
var newArray1 = this.arr.map(function(row) {
// this === (outer this)
var mUPC = this.removeLeadingZero(row[0]);
// ...
}.bind(this)); // bind the function to this
Store a reference to the outer this:
var self = this;
var newArray1 = this.arr.map(function(row) {
// self === (outer this)
var mUPC = self.removeLeadingZero(row[0]);
// ...
});
Use an arrow function:
var newArray1 = this.arr.map(row => {
// this === (outer this)
var mUPC = this.removeLeadingZero(row[0]);
// ...
});
Additionally, you could stop using this and new.
I have solved this issue and below is the answer in case anyone else runs into this:
this needs to be placed into a variable:
var _this = this;
and then you can call it within the object:
var mUPC = _this.removeLeadingZero(row[0])
Javascript scope strikes again!

Cannot reduce array inside of an object

I am trying to reduce an array inside of an object. I am getting back
push is not a function
I have started my array as empty and created a add function to pass in as the first argument.
function add(a,b) {
return a +b;
}
var navBarArray = [];
var listArray = [];
var mapping = {
".navbar": navBarArray,
".list-group": listArray
};
I tried this approach on the mapping object but it creates errors
var mapping = {
".navbar": Math.round(navBarArray.reduce(add,0) ),
".list-group": listArray
};
However, I get push is not a function back in my console.
Below is my function that passes values to the array. I can create a variable inside the function and reduce it there. However, that limits access to my variable and will bloat my function as I continue.
Object.keys(mapping).forEach(function(selector) {
$(selector).hover(function(evt) {
console.log('mapping',mapping);
console.log('selector',selector);
enteredTime = new Date();
}, function() {
var ctime = new Date();
var time = (ctime.getTime() - enteredTime.getTime())/1000;
mapping[selector].push(time);
// *********** this works but not where I need it to*******
var reduce = Math.round(navBarArray.reduce(add,0) );
console.log(reduce);
});
})
Change your mapping object so it has separate places for the array and total:
var mapping = {
".navbar": {
total: 0,
times: []
},
".list-group": {
total: 0,
times: []
}
}
Then you do mapping[selector].times.push(time), and put the total with:
mapping[selector].total = mapping[selector].times.reduce(add, 0);

Why can I not access an array in factory while I am in a forEach loop with Angular?

I have the following question: Why is it impossible for me to access my array in a forEach loop with Angular. I have made this factory with an array and a function, within the function I have this forEach loop. Outside of the forEach loop I can acces my array with the this keyword. In the forEach loop it gives me a undefined value.
.factory("sendOrder", function () {
return {
paired: [],
send: function () {
var names = document.getElementsByTagName('input');
var ordered = document.getElementsByClassName('ordered');
var i = 0;
console.log(this.paired);//I can access it from here
angular.forEach(names, function (amount, key) {
console.log(this.paired);//Unable to access
i++;
return;
})
}
}
})
Maybe this will help. Angular lets you set the context (this) in forEach. It's one of the arguments. You don't have to set any other variables:
angular.forEach(obj, iterator, [context]);
You've passed in obj and iterator. Just pass in something for context and that will be this in the function.
Because the context of the function changes - this is not what it originally was. The usual fix is to set the original context to a variably (usually called self):
.factory("sendOrder", function () {
return {
paired: [],
send: function () {
var self = this;
var names = document.getElementsByTagName('input');
var ordered = document.getElementsByClassName('ordered');
var i = 0;
console.log(this.paired);//I can access it from here
angular.forEach(names, function (amount, key) {
console.log(self.paired);//should be fine now
i++;
return;
})
}
}
})

Categories