Issue
The API Returns an array of objects so that i could extract it and loop it through and make ROWS out of it . but the problem is it displays only one element in the row and makes 2 entries of Rows . but When i click on the choose files options (there is a column in which we can choose files) and give a file path . the data of the other row displays also there is a file extension column which is a drop down . the data from this drop down also comes from an API .this functionality works when i add a path to the file . i think there is some rendering issue . This is my HTML code for the table
<div class="card" >
<hr>
<div class="card-header">
<h2>Bank Statements of {{this.selectedOptionProduct}}</h2>
</div>
<div class="card-body">
<div class="loading-spinner" *ngIf="productSelectedForLoading && loading">
<div class="spinner"></div>
</div>
<table class="table" >
<thead>
<tr>
<th>Product Name</th>
<th>File Uploads</th>
<th>Status</th>
<th> File extenstion </th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tableData " >
<td>{{ row.file_type_id }}</td>
<td>
<input type="file" #fileInput [value]="row.file_type_id" (change)="onFileSelected($event, row)">
<button (click)="uploadFile(row)">Upload</button>
<button (click)="resetFileInput(fileInput)">Reset</button>
</td>
<td>{{ row.status }}</td>
<td>
<select (change)="onOptionSelectedExtention($event.target)" >
<option>Select one </option>
<option *ngFor="let extention of row.file_extensions" mat-menu-item [value]="extention" >{{extention}}</option>
</select>
</td>
</tr>
</tbody>
</table>
This is my component.ts file for those functions
tableData: any[] = [
];
selectedExtention : String
loading: boolean = true;
onOptionSelectedExtention(selectedOption : any){
this.selectedExtention=selectedOption.value
console.log(this.selectedExtention)
}
async getTableData(selectedProduct: any) {
try {
const url = `API?product_id=${selectedProduct}`;
const response = await axios.get(url);
const data = response.data;
this.tableData = data;
this.loading = false;
console.log(this.tableData);
// Flatten the tableData array
this.flattenedTableData = this.tableData.reduce((accumulator, row) => {
return accumulator.concat(row.items);
}, []);
console.log(this.flattenedTableData);
// Use the variable as needed
console.log(data);
} catch (error) {
// Handle any errors
console.error('Error:', error);
}
}
resetFileInput(fileInput: HTMLInputElement) {
fileInput.value = ''; // Reset the value of the file input field
}
onFileSelected(event: any, row: any) {
row.selectedFile = event.target.files[0];
console.log(row.selectedFile['name'])
}
uploadFile(row: any) {
const file = row.selectedFile;
console.log(file);
if (file) {
const formData = new FormData();
formData.append('file', file);
// Make an HTTP request to upload the file
this.http.post('your-upload-api-url', formData)
.subscribe(
response => {
// Handle success response, e.g., update status
row.status = 'Uploaded';
},
error => {
// Handle error response, e.g., display an error message
console.log("hello")
}
);
}
}
And this only happens when i have two objects in that array from the API . how to fix it . here are some of the SS for visual representation. This picture is when i don't hit choose the file option as you could see this does not render the second row items neither the file extension
edit :
This is after hitting choose files and it re rendered
The API response for the table
The updated image when i choose the file path
Solution
The problem is that you are using property binding rather than just assigning a a string value to your input. Therefor, the first row renders correctly, but when the second row is rendered, there is a conflict as the property is already bound to the first row's input. This results in the following DOM exception:
"ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string."
You can resolve this by simply removing brackets on your [value] property. This will assign a string value rather that binding the property.
Ex.
<td>
<input type="file" #fileInput value="row.file_type_id" (change)="onFileSelected($event, row)">
<button (click)="uploadFile(row)">Upload</button>
<button (click)="resetFileInput(fileInput)">Reset</button>
</td>
Answered By - De Wet van As
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.