I am pretty new to angular but I cannot seem to understand how this seems to be running asynchronously? (if that is whats happening)
I simply wanted to call the parseData
method in my batchservice.ts
and store the data into localStorage
then retrieve the data but it seems that when I'm trying to retrieve it, its always null.
@Output() onUploaded: EventEmitter<void> = new EventEmitter<void>();
onFileUpload(event: any) {
localStorage.clear();
this.uploadFile = event?.target.files[0];
if (this.uploadFile) {
this.fileName = this.uploadFile.name
this.batchService.parseData(this.uploadFile)
}
this.onUploaded.emit();
<batch-upload (onUploaded)="loadStoredData()"></batch-upload>
batchservice.ts
parseData(uploadFile: File) {
this.upFile = uploadFile
this.header = (this.header as unknown as string) === 'true' || this.header === true;
this.ngxCsvParser.parse(uploadFile, { header: this.header, delimiter: ',' })
.pipe().subscribe({
next: (result): void => {
this.csvRow = result;
for (let i = 1; i < this.csvRow.length; i) {
const rowData =
{
'time': this.csvRow[i][0].trim(),
'name': this.csvRow[i][1].trim(),
'dob': this.csvRow[i][2].trim(),
'phone': this.csvRow[i][3].trim(),
'type': this.csvRow[i][4].trim(),
'comment': this.csvRow[i][5].trim(),
}
localStorage.setItem(("row" i), JSON.stringify(rowData))
console.log("localStorage item set")
}
},
error: (error: NgxCSVParserError): void => {
console.log('Error', error);
}
});
}
Running console.log
always outputs in my loadStoredData
method before console output in my parseData
loadStoredData() {
console.log("loading stored data!")
let row = localStorage.getItem('row1');
let temp = JSON.parse(row!)
console.log(temp.name)
}
this would be a snippet of my console output:
loading stored data!
ERROR: TypeError: Cannot read properties of null...
localStorage item set!
I dont understand how the output for loading is coming before the localStorage item set.
CodePudding user response:
this.onUploaded.emit();
wrap this with setTimeout() with some delay,
setTimeout(() => this.onUploaded.emit(),1000)
while js is compiling it will run line by line, so when it sees subscribe(in your case it is there here this.ngxCsvParser.parse(uploadFile, { header: this.header, delimiter: ',' }) .pipe().subscribe({
so it will push this in another queue and continue its compiling so this.onuploaded.emit() is executing even before values are set in local storage so , the solution would be setTimeout with some delay should solve the problem
but using settimeout is not optimal solution when you are dealing with large data parsing times might be high and setTimeout may execute even before parsing so you need to some how call this.onUploaded() inside callback function of subscribe maybe using pubsub or move the parsedata function inside component