Javascript for loop not getting length inside another for loop - javascript

I am trying to loop through my json value obtain from my server which is like this:
[
{
below_min: [
{
y: 0,
label: "Bhagalpur",
color: "Red"
},
{
y: 0,
label: "Gopalganj",
color: "Red"
}
]
},
{
min: [
{
y: 0.2,
label: "Samastipur",
color: "Orange"
},
{
y: 0.3,
label: "Saran",
color: "Orange"
}
}
]
}
]
I am using this loop code to get the value of my below_min array:
for (let index = 0; index < res.length; index++) {
const element = res[index];
console.log(element.below_min);
// const u = element.below_min
for (let index = 0; index < element.below_min.length; index++) {
const h = element.below_min[index];
}
}
but I am getting error:
ERROR TypeError: Cannot read property 'length' of undefined
I have tried few things such as when I am trying to see what is this below_min as type of I am seeing this as an object. My question is what is wrong with my code.

Your Javascript Object literal has syntax issue. so i tried to correct it.
You can try the following code and get the idea about getting below_min correctly:
const res = [
{
below_min: [
{
y: 0,
label: "Bhagalpur",
color: "Red"
},
{
y: 0,
label: "Gopalganj",
color: "Red"
}
]
},
{
min: [
{
y: 0.2,
label: "Samastipur",
color: "Orange"
},
{
y: 0.3,
label: "Saran",
color: "Orange"
}
]
}
];
for (let index = 0; index < res.length; index++) {
const element = res[index];
if(element.below_min){
for (let minIndex = 0; minIndex < element.below_min.length; minIndex++) {
const h = element.below_min[minIndex];
console.log(h);
}
}
}

Your list contains a lot of elements that doesn't have below_min property and when you want to reach the property it will return undefined.

Related

React Array TypeError: Cannot read properties of undefined (reading 'length')

I'm using chart.js to create a chart.
Declare data: minsu by importing Array named minsu in data.
And according to the minsu value, green if greater than 100
A conditional statement is created with a 'yellow if less than 100' for statement.
But I get an error with the for (let i =0 i < dataset.data.length; i++) syntax.
TypeError: Cannot read properties of undefined (reading 'length')
If I modify the code in the for conditional statement, it will render properly, but I do not know how to modify the code.
let minsu = ProductDetail && ProductDetail.materialsInfo.map(array => array.chartPercentage)
console.log(minsu); // Array [100, 50, 20, 60, 120]
let chartColors = {
yellow: 'rgb(244, 208, 104)',
green: '#4CC26F',
gray: '#EBEBEB'
};
const data = {
datasets: [
{
backgroundColor: [],
data: minsu,
},
],
};
console.log(data); // Array [100, 50, 20, 60, 120]
// The reference value is 100 .
let colorChangeValue = 100;
let dataset = data.datasets[0];
for (let i = 0; i < dataset.data.length; i++) {
if (dataset.data[i] > colorChangeValue) {
dataset.backgroundColor[i] = chartColors.green;
if (dataset.data[i] < 100) {
dataset.backgroundColor[i] = chartColors.gray;
}
}
if (dataset.data[i] < colorChangeValue) {
dataset.backgroundColor[i] = chartColors.yellow;
}
}

Insertion sort on an array of objects with javascript

I have this array with objects that look like this
{
n: 15,
color: "red"
}
I am trying to sort it with the below function
async insertionSort() {
let len = this.array.length;
let value;
let i;
let j;
//let current;
// let arr = this.array;
for (i = 0; i < len; i++) {
value = this.array[i].n;
//current = this.array[i];
for (j = i - 1; j > -1 && this.array[j].n > value; j++) {
//arr[j + 1] = arr[j];
// HF.arraySwap(this.array, this.array[j + 1], this.array[j]);
this.array[j + 1] = this.array[j];
}
// arr[j + 1] = value;
HF.arraySwap(this.array, this.array[j + 1], this.array[i]);
await HF.sleep();
}
}
** I cant use array.sort(...) because i am trying to make a visualization of the algorithm, i am using objects in order to change the color of the bars i am rendering on the screen **
When i hit the second for loop i get an error of "Cannot read property 'n' of undefined", when i run it with just numbers it works fine but when i try it with objects it gives the error.I know now i am running out of the array, is there a way i can overcome this and still sort the array of objects? Also, i am using VueJS to display all of this
Try against this.array[i].n write this.array[i][n]
And against this.array[j].n write this.array[j][n]
On the first iteration i=0, you start second loop with value j=i-1 which is -1. Array doesn't contain item with index -1: array[-1] is undefined. As soon as JavaScript can compare variables of different types it works with numbers because comparison of number and undefined won't trigger an error
By the way you can use Array.proototype.sort method, it will look like:
console.log(myArr.sort((a,b) => a.n - b.n))
<script>
const myArr = [
{ n: 1, color: "red" },
{ n: 44, color: "orange" },
{ n: 13, color: "yellow" },
{ n: 8, color: "green" },
{ n: 2, color: "blue" }
];
</script>
Is there any reason why not use sort method like this?:
const arr = [
{ n: 10, color: "red" },
{ n: 20, color: "yellow" },
{ n: 15, color: "black" },
{ n: 7, color: "white" },
{ n: 23, color: "blue" }
];
const ascSorted = arr.sort((a, b) => a.n - b.n);
const descSorted = arr.sort((a, b) => b.n - a.n);
console.log(ascSorted);
// [
// { n: 7, color: "white" },
// { n: 10, color: "red" },
// { n: 15, color: "black" },
// { n: 20, color: "yellow" },
// { n: 23, color: "blue" }
// ];

How to clear the vue warn when I use vue-slider-component?

The issue detail:
1. I implement the feature with the vue-slider-component module, but that has a lot of warnings when I move the dots on the slider.
2. I know that the reason is that I used v-for to point to an object that will change, but I do not know how to fix this issue.
the following link is my test site:
https://jsfiddle.net/ncwv84x9/
enter image description here
My codes:
code1 (Html)
<div id="app">
<div class="box" v-for="(item,index) in columnvalue">
<label>{{item.text}}</label>
<input v-model="value[index]" />
</div>
<hr />
<br />
<vue-slider v-model="value" :order="false" :tooltip="'always'" :process="false" :marks="marks" :width="600">
<template slot="tooltip" slot-scope="{index}">
<div>{{getText(index)}}</div>
</template>
</vue-slider>
</div>
JavaScript + Vue:
new Vue({
el: '#app',
components: {
VueSlider: window['vue-slider-component']
},
data: function() {
return {
// collect the all values
columnvalue: [],
// stored disease value
pet_name: [{
text: 'dog',
index: 0
},
{
text: 'cat',
index: 1
}
],
// stored drug value
feeder_name: [{
text: 'Sam',
index: 0
}],
// from age filter
age: [
65, 100
],
test: "",
value: [],
process: dotsPos => [
[dotsPos[0], dotsPos[1], {
backgroundColor: 'pink'
}],
[dotsPos[1], dotsPos[2], {
backgroundColor: 'blue'
}],
[dotsPos[2], dotsPos[3], {
backgroundColor: 'black'
}],
],
after: {},
relations: [],
marks: {
'0': {
label: 'start',
margin: '0 0 0 10px'
},
'100': {
label: 'end',
labelStyle: {
left: '100%',
margin: '0 0 0 10px',
top: '50%',
transform: 'translateY(-50%)'
}
}
}
}
},
created: function() {
//vue instance 被 constructor 建立後,在這裡完成 data binding
let tmpArray = this.pet_name.concat(this.feeder_name);
let tmpValueArray = [];
for (i = 0; i < tmpArray.length; i++) {
tmpArray[i].index = i;
tmpValueArray.push(0);
}
this.columnvalue = tmpArray;
this.value = tmpValueArray;
},
methods: {
getText(index) {
const ani = this.columnvalue.find((v) => v.index == index).text;
this.after = {
...this.after,
[ani]: this.value[index]
}
return ani;
},
getNodeRelation() {
const indexs = this.after;
let result = [];
let result2 = [];
let placement = [];
for (obj in indexs) {
placement.push([obj, indexs[obj]]);
}
placement.sort(function(a, b) {
/* console.log(a[1]) */
return a[1] - b[1];
})
for (i = 0; i < placement.length; i++) {
if (i + 1 >= placement.length) {
break;
}
let distance = placement[i + 1][1] - placement[i][1];
let predicate = "";
if (distance > 0) {
predicate = "after";
} else if (distance == 0 && placement[i + 1][1] == 0) {
predicate = "hasUse";
} else {
predicate = "same";
}
let source = {
label: placement[i][0],
index: i
};
let target = {
label: placement[i + 1][0],
index: i
};
// store the 4-tuple reprsentations about slider
result2.push({
source: source,
target: target,
type: predicate,
days: distance
});
}
/* this.relations = "{\"relation\":" + JSON.stringify(result2)+"}" */
;
this.relations = JSON.stringify(result2);
},
getAllFilters() {
let vm = this;
let beginHas = true;
if (vm.relations.length == 0) {
vm.getNodeRelation();
beginHas = false;
}
let result = {
age: vm.age,
disease_name: vm.disease_name,
drug_name: vm.drug_name,
relation: vm.relations
};
if (!beginHas) {
vm.relations = [];
}
this.test = JSON.stringify(result);
}
},
})
I get a infinite loop error which disappears when I remove this section in getText()
this.after = {
...this.after,
[ani]: this.value[index]
}
This is because there is some reactivity triggered and re-renders the dom, which calls that function, which renders the dom and so on...

Compare two Objects and determine the parent node of differed properties

I have a scenario, were need to compare treeObject1 and treeObject2 to determine the exact difference at property level and find the parent of modified node.
In below provided objects, I need to get output as color blue. Since the difference is at otherObj2.
treeObject1 = {
color: "red",
value: 10,
otherObj: {
color: "blue",
otherObj2: {
otherColor: "blue",
otherValue: 20,
}
}
}
treeObject2 = {
color: "red",
value: 10,
otherObj: {
color: "blue",
otherObj2: {
otherColor: "Green",
otherValue: 20,
}
}
}
If you want the key "otherObj" as well let me know, that can easily be added. Otherwise here is a working version of what you were looking for.
This uses a combination of Object.keys and every
treeObject1 = {
color: "red",
value: 10,
otherObj: {
color: "blue",
otherObj2: {
otherColor: "blue",
otherValue: 20,
}
}
}
treeObject2 = {
color: "red",
value: 10,
otherObj: {
color: "blue",
otherObj2: {
otherColor: "Green",
otherValue: 20,
}
}
}
const findParentNode = (obj1, obj2, parent = null) => {
if(parent === null) parent = obj2;
//since the structures are the same we only get keys from the first object
const keys = Object.keys(obj1);
let result = null;
//iterate through every key
keys.every(key=>{
//if it's an object... then we recall findParentNode (recursive)
if(obj1[key] instanceof Object){
result = findParentNode(obj1[key], obj2[key], obj2);
//If result from findParentNode is not null then a difference was found.
//Return false to stop the every method.
if(result !== null) return false;
}else if(obj1[key] !== obj2[key]){
//If the objects are different we found a difference
//Set the parent as the difference
result = parent;
return false;
}
//return true to keep on looping
return true;
});
//return the result
return result;
}
console.log(findParentNode(treeObject1, treeObject2));
** note that the above snippet will return "null" if nothing was found. **
You could use a nested approach for objects and by checking the values.
function getDiffParents(object1, object2, parent = {}) {
return Object.assign(...Object.entries(object1).map(([k, v]) => v && typeof v === 'object'
? getDiffParents(v, object2[k], object1)
: v === object2[k]
? {}
: parent
));
}
var treeObject1 = { color: "red", value: 10, otherObj: { color: "blue", otherObj2: { otherColor: "blue", otherValue: 20 } } },
treeObject2 = { color: "red", value: 10, otherObj: { color: "blue", otherObj2: { otherColor: "Green", otherValue: 20 } } };
console.log(getDiffParents(treeObject1, treeObject2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Extracting multi-dimentsional arrays in Javascript/JQuery

I'm extracting some data from an SQL source, which I can get into a javascript script as a simple array (shown grouped by dates) which consists of week no, task number and hours spent:
mydata = [
// weekno, taskno, hours
["2014-14",160,37.5],
["2014-15",160,30],
["2014-15",243,7.5],
["2014-16",160,37.5],
["2014-17",0,7.5],
["2014-17",3,7.5],
["2014-17",321,22.5],
["2014-18",0,7.5],
["2014-18",321,30],
["2014-19",3,7.5],
["2014-19",295,30]
];
I'm going to be charting it using HighCharts, and I need to get it into two property arrays like this:
properties = {
categories: [ "2014-14","2014-15","2014-16","2014-17","2014-18","2014-19"],
series: [
// Task Week
// No 14 15 16 17 18 19
//
{ name: '0', data: [ 0, 0, 0, 7.5, 7.5, 0 ] },
{ name: '3', data: [ 0, 0, 0, 7.5, 0, 7.5 ] },
{ name: '160', data: [ 37.5, 30, 37.5, 0, 0, 0 ] },
{ name: '243', data: [ 0, 7.5, 0, 0, 0, 0 ] },
{ name: '295', data: [ 0, 0, 0, 0, 0, 30 ] },
{ name: '321', data: [ 0, 0, 0, 22.5, 30, 0 ] }
]
}
Aside from looping, am I missing some succinct, idiomatic method for doing this?
In case it's of use to anyone, here's a cobbled together solution:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
var categories = [];
var subcategories = [];
var temp = {};
for (var i = 0; i < myChartData.length; i++) {
key = myChartData[i][0];
taskno = myChartData[i][1];
hours = myChartData[i][2];
if (taskno in temp == false) temp[taskno] = {};
if (key in temp[taskno] == false) temp[taskno][key] = 0;
temp[taskno][key] += hours;
categories.push(myChartData[i][0]);
subcategories.push(myChartData[i][1])
}
var uniqueCategories = categories.filter(onlyUnique).sort();
var uniqueSubcategories = subcategories.filter(onlyUnique).sort(function(a, b) {
return a - b
});
var series = [];
for (var i = 0; i < uniqueSubcategories.length; i++) {
subcatKey = uniqueSubcategories[i];
series[i] = { name: 'Task ' + subcatKey, data: [] };
for (var j = 0; j < uniqueCategories.length; j++) {
catKey = uniqueCategories[j];
series[i]['data'].push(temp[subcatKey][catKey] ? temp[subcatKey][catKey] : 0);
}
}
where series and uniqueCategories are the required data.

Categories