Parent component displays the data correctly but it is not sending the asynchronously populated data to the child component
I am new to Angular and I am following its documentation from this page: https://angular.io/guide/component-interaction I am able to read file details into a parent component asynchronously using an Angular service. When I display the file details from the parent component, I can see that the file was read correctly. When I am passing the data using @Output() variable and receiving it in the child component using @Input, I am getting empty data as if the child component received the Input synchronously but not asynchronously.
Here's the service:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import {inFile} from '../Classes/inFile';
@Injectable({
providedIn: 'root'
})
export class AddFilesService {
inFileObj = new inFile();
inFiles:any = [];
constructor(private http:HttpClient) { }
uploadFiles(event){
const files = event.target.files;
for (let i=0; i<= files.length-1 ; i++){
const file = files[i];
const fileName = file.name;
const reader = new FileReader();
//ASYNCHRONOUS FILE READ
reader.onload = () => {
this.inFileObj.name = fileName;
this.inFileObj.size = file.size;
};
reader.readAsArrayBuffer(file);
}
this.inFiles.push(this.inFileObj);
return of(this.inFiles);
}
}
Here's the parent component component that takes a file input and displays file name and file size:
import { Component, OnInit, Output } from '@angular/core';
import {AddFilesService} from '../../services/add-files.service';
@Component({
selector: 'app-input-form',
templateUrl: './input-form.component.html',
styleUrls: ['./input-form.component.css']
})
export class InputFormComponent implements OnInit {
inFiles:any = [];
@Output() uploadedFileDetails:string;
constructor(private addFilesService: AddFilesService) { }
ngOnInit() {
}
fileUpload(event) : void {
this.addFilesService.uploadFiles(event).subscribe(
data => {
//THIS WORKS
this.inFiles = data;
//THIS DOES NOT WORK
this.uploadedFileDetails = data;
},
error =>{
console.log(error);
}
);
}
}
Here's the parent HTML template:
`<input type="file" (change)="fileUpload($event)" multiple>
<table>
<tbody>
<tr *ngFor = "let inFile of inFiles">
<td>Name from Parent: {{inFile.name}}</td>
<td>Size from Parent: {{inFile.size}}</td>
</tr>
</tbody>
</table>`
Output from parent component:
Name from Parent: Test.txt Size from Parent: 57
Here's the child component:
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css'],
})
export class MapComponent implements OnInit {
@Input() uploadedFileDetails:string;
constructor() {}
ngOnInit() {
}
}
Here's the child HTML which has no output:
`<table>
<tbody>
<tr *ngFor = "let inFile of uploadedFileDetails">
<td>Name from Child: {{inFile.name}}</td>
<td>Size from Child: {{inFile.size}}</td>
</tr>
</tbody>
</table>`
<app-map [uploadedFileDetails]="uploadedFileDetails"><app-map>in your parent html? - Fateme Fazli