I am trying to return a value that is situated within a matrix made up of arrays and nested arrays.
I am having trouble achieving this. My current approach is this:
//coords = 2,2,1,1,0
const addPrefix = (coords: []) => {
const completeCoords = (coords: []) => {
return coords.map((c) => {
return complex[c[0]][c[1]];
});
};
const values = completeCoords(coords);
console.log(values);
};
This current approach just returns this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'undefined')
Related
I'm working on a VueJS component that, among other things, can export data to .xlsx. For this, I'm using the json2xls library - so I need to pass to the json2xls() function an array of objects with identical keys (said keys will be column names)
This data I have to export is in an array of pretty deeply nested objects, though, so I need a function that will process that data to a form that will work with json2xls.
This is the method I'm using for that:
exportReport () {
const dataMap = []
this.reportPreview.forEach(elm => {
const auxObj = {}
auxObj.name = `${elm.client.first_name} ${elm.client.surname_1} ${elm.client.surname_2}`
elm.legal_files.forEach((e) => {
auxObj.legalfile = e.code
auxObj.actions = e.actions.count
dataMap.push(auxObj)
})
})
exportToXls(dataMap, `action-report-by-client-${this.options.start_date}-${this.options.end_date}.xlsx`)
}
If I do this, however, it appears that in cycles of elm.legal_files.forEach() the properties auxObj.legalfile and auxObj.actions are not overwritten, pushing several objects with identical values to dataMap
Why is this happening? What am I doing wrong? I'm hacking my way around this copying auxObj after "overwriting" the legalfile and actions properties and pushing the copy. This hack works, but I wonder what causes the first behavior and if there's a cleaner way around it.
exportReport () {
const dataMap = []
this.reportPreview.forEach(elm => {
const auxObj = {}
auxObj.name = `${elm.client.first_name} ${elm.client.surname_1} ${elm.client.surname_2}`
elm.legal_files.forEach((e) => {
auxObj.legalfile = e.code
auxObj.actions = e.actions.count
/*
If I just push auxObj to dataMap, the object is pushed with the same properties every time.
Copying auxObj and pushing the copy is a hack around this problem, but there may be a cleaner solution.
*/
const objCopy = { ...auxObj }
dataMap.push(objCopy)
})
})
exportToXls(dataMap, `action-report-by-client-${this.options.start_date}-${this.options.end_date}.xlsx`)
}
You pushed the same object every time.
exportReport() {
const dataMap = []
this.reportPreview.forEach(elm => {
const name = `${elm.client.first_name} ${elm.client.surname_1} ${elm.client.surname_2}`
elm.legal_files.forEach((e) => {
const auxObj = {} // Create a new object here
auxObj.name = name
auxObj.legalfile = e.code
auxObj.actions = e.actions.count
dataMap.push(auxObj) // Push it into the array
})
})
exportToXls(dataMap, `action-report-by-client-${this.options.start_date}-${this.options.end_date}.xlsx`)
}
I have the following in componentDidMount
componentDidMount() {
const company = this.props.location.state.company;
const financials = this.props.location.state.financials;
let { values } = this.state;
values = EDITABLES.map((data) => { //EDITABLES is a const imported array
return {
id: data.id,
name: data.name,
value: financials[data.id]
newValue: "",
};
});
this.setState({
values,
});
}
However, if I console.log the values at the time of render, the first console log shows it as undefined, but the next one shows it as defined. I am also able to map the values in my render method without any problem.
render() {
const {
company,
financials,
values,
} = this.state;
console.log(values, "check")
My problem is that in my render method, I call a function {this.calculate(financial.id)}
calculate(financial) {
const { financials, values } = this.state;
console.log(values, "values");
let numerator;
if (financial === "tev_profit") { //this line is okay
let tev = values.find(o => o.id === "total_value");
console.log(tev, "here");
numerator = tev.newValue; //this line is causing error.
From the console log it seems as if tev is sometimes defined but other times not. I'm not sure where I'm going wrong because I also added this to my code but still facing the same typeError:
this.calculate = this.calculate.bind(this);
Update:
I have tried adding if(values) to my calculate function before I go into any other if block, but getting the same error
Issue
Array.prototype.find can return undefined if element isn't found.
The find() method returns the value of the first element in the
provided array that satisfies the provided testing function. If no
values satisfy the testing function, undefined is returned.
Solution
Check for valid tev object before accessing properties
if (financial === "tev_over_ltm_gross_profit") {
const tev = values.find(o => o.id === "total_enterprise_value");
if (tev) {
// tev exists
numerator = tev.newValue;
}
I tried an iteration using Vue.js
The result Got an error like this
[Vue warn]: Error in mounted hook: "TypeError: this.frontImages.forEach is not a function"
this.frontImages = {frontA:{name:'frontAName'},frontB:{name:'frontBName'}};
this.frontImages.forEach(function(value, index) {
console.log(value);
}
.forEach() will only work for arrays.
If you need to iterate through the properties of a JSON object, then here is one way of doing that:
this.frontImages = {frontA:{name:'frontAName'},frontB:{name:'frontBName'}};
printKeysAndValues(this.frontImages);
function printKeysAndValues(anyObject) {
Object.keys(anyObject).forEach( key => {
// in-case properties are nested objects
let value = JSON.stringify(anyObject[key]);
// let value = anyObject[key]; // for primitive nested properties
console.log(`${key} = ${value}`);
});
}
For array:
this.frontImages = [{frontA:{name:'frontAName'},frontB:{name:'frontBName'}}];
this.frontImages.forEach(function(value, index) {
console.log(value);
})
For only object iteration
this.frontImages = {frontA:{name:'frontAName'},frontB:{name:'frontBName'}};
Object.values(this.frontImages).forEach(value => {
console.log(value);
});
const addressZip = person.get('addresses').filter((address) => address.get('legacy_id')).filter((newAddress) => (
getZIPErrors(newAddress.get('zip'))
))
when this function is executed it returns me as an
[array(0)] if it has no error
when it has an error it returns me as an [array(1)].
Instead of returning an array inside an array I just want to return a single array in this way if it has no error [] and if it has an error it should be like ['invalid']
You can implement a concatAll method within Array constructor, then use it to flatten your result:
Array.prototype.concatAll = function() {
return this.reduce((acc, curr) => acc = acc.concat(curr))
}
const addressZip = person
.get('addresses')
.filter(address => address.get('legacy_id'))
.filter(newAddress => getZIPErrors(newAddress.get('zip')))
.concatAll()
I'm trying to make an application with Angular 2. Now I ran into a problem which I can't solve.
One of the functions of an array should be push(object: T);
I defined an array of an object that I made. But when I try to add values to this array I receive the following error: TypeError: Cannot read property 'push' of undefined.
One of the main causes of this error is people forgetting to define their array. But I'm defining it, I tried it in multiple ways but still the same error.
export class Home {
activeDossiers: Array<Dossier> = new Array();
//Also tried:
//activeDossiers: Dossier[] = [];
//activeDossiers = [];
//activeDossiers: Array<Dossier> = [];
constructor() {
var dossierApi = new DossierApi();
dossierApi.getActiveDossiers().then((dossiers) => {
dossiers.forEach(function (obj, i) {
console.log(obj);
if(obj.dossierType === Values.Visible) {
this.activeDossiers.push(obj);
}
});
});
}
}
You are using the anonymous function() syntax for the callback; this syntax does NOT preserve the this. Instead do:
dossiers.forEach((obj, i) => { // IMPORTANT PART HERE!!!
console.log(obj);
if(obj.dossierType === Values.Visible) {
this.activeDossiers.push(obj);
}
});