Angular project with identical code to example yields empty error
Closed this issue · 11 comments
Hello!
I am trying to implement this in an angular application.
I have attempted to use both overloads of the parseISOXMLFile function like so;
onFileSelected(event: Event) {
const files = (event.target as HTMLInputElement).files;
const isoxmlManager = new ISOXMLManager();
if (files && files.length > 0) {
const file = files[0];
jsZip.loadAsync(file).then((zip) => {
zip.files["TASKDATA/TASKDATA.XML"].async('string').then((fileData) => {
try {
isoxmlManager.parseISOXMLFile(fileData, 'application/xml').then(() => {
// getWarnings() method returns all the warnings from the last parsing
console.log(isoxmlManager.getWarnings())
// all global attributes of the parsed file
console.log(isoxmlManager.options)
// get all the Partfileds
const partfields: Partfield[] = isoxmlManager.rootElement.attributes.Partfield || []
// print designators of all the Partfields
partfields.forEach(partfield => {
console.log(`${partfield.attributes.PartfieldDesignator}`)
})
})
} catch(e) {
console.log(e)
}
});
});
}
}
And
onFileSelected(event: Event) {
const files = (event.target as HTMLInputElement).files;
const isoxmlManager = new ISOXMLManager();
if (files && files.length > 0) {
const file = files[0];
const reader = new FileReader()
reader.onload = async () => {
const array = new Uint8Array(reader.result as ArrayBuffer)
try {
await isoxmlManager.parseISOXMLFile(array, 'application/zip').then(() => {
// getWarnings() method returns all the warnings from the last parsing
console.log(isoxmlManager.getWarnings())
// all global attributes of the parsed file
console.log(isoxmlManager.options)
// get all the Partfileds
const partfields: Partfield[] = isoxmlManager.rootElement.attributes.Partfield || []
// print designators of all the Partfields
partfields.forEach(partfield => {
console.log(`${partfield.attributes.PartfieldDesignator}`)
})
})
} catch(e) {
console.log(e)
}
}
reader.readAsArrayBuffer(file)
}
}
In both instances I am getting the following error:
The error indicates that it is essentially an empty file I am trying to look at
I have tried to modifiy the settings, but it is the same error no matter what I do
The file used, comes from a legitimate source, and works perfectly fine in other tools used to verify and showcase the content
Hi @alkrdev , thank you for reporting this issue!
The errors look weird, particularly part PDV[first]
. Internally, XML is parsed to JSON, and then JSON is converted to JS classes. During that conversion, we iterate over arrays in the following way. My guess is that Angular or one of your dependencies adds additional methods to Array prototype (isEmpty
, first
, last
), which breaks for..in loops in our code...
I'll try to fix this issue in our sources ASAP and will let you know.
Unfortunately still getting the same error;
Here's a slightly better image of the error. Do you need more context or information? Let me know and I will provide it.
I am not sure if it is relevant, but the isoxmlManager.getWarnings() function is placed in the catch, instead of inside the try - Which deviates from the examples.
@alkrdev Thanks for checking the version! At this point, I don't have good ideas of what's happening in your environment. I can't reproduce this error locally...
I have the following ideas about how we can debug it:
- (the best option) Is it possible to create a standalone minimal reproducible example of this problem? Something that I can run locally and see that error.
- (just in case - I don't think that it's the source of the problem) Is it possible to send me the ISOXML file you are using for testing?
- Could you dump Array and Object prototypes from your environment (e.g. in browser with running Angular application)?
Object.keys(Object.prototype)
Object.keys(Array.prototype)
for ([idx, item] of ['a'].entries()) {console.log(idx, item)}
for (key of Object.keys({a: 1})) {console.log(key)}
I hunted down and removed the 3 pollutants which were apparently added as extensions to the Array.prototype, and now it is working correctly.
I am assuming the way to reproduce this, would be to undo the changes I have just made;
From a newly created Angular project, inset the following:
/src/app/core/extensions/array.extensions.ts
/src/app/core/extensions/index.ts
In index.ts, add the following:
export * from './array.extensions';
In array.extensions.ts, add the following:
declare global {
interface Array<T> {
/**
* Returns true if the array is empty. False otherwise.
*/
isEmpty(): boolean;
/**
* Returns the first element of the array
*/
first(): T | undefined;
/**
* Returns the last element of the array
*/
last(): T | undefined;
}
}
if (!Array.prototype.isEmpty) {
Array.prototype.isEmpty = function () {
return this.length === 0;
};
}
if (!Array.prototype.first) {
Array.prototype.first = function () {
return this[0];
};
}
if (!Array.prototype.last) {
Array.prototype.last = function () {
return this[this.length - 1];
};
}
export {};
in the following file:
/src/main.ts
Add the following to the imports:
import './app/core/extensions';
@alkrdev Thanks for the dumps of prototypes and description of minimal reproducible prototype. What I don't understand is why the fix I made doesn't work - it's supposed to handle issues with exactly this type of Array.prototype pollution... Your output of test for
's above demonstrates that it should work in your environment... I'll try to reproduce it with Angular + files above tonight.
@aparshin Hey, different account, same person;
I will gladly concede that I somehow messed up on my end, and the changes you submitted probably didn't apply on my end, somehow..
If you want more information on the setup on my side, please let me know, as far as I am concerned it seems to work perfectly fine now, due to your changes.
@alexanderseges @alkrdev Glad to hear that! The fix is published in npm as v1.9.2. And thanks for reporting one more time!