Here i will paste what sould be the relevant code to my error and at the end I will explain what doesn't work. I will also paste a picture of what the HTML page looks like.
Also, I cut out what I think should not be needed for this problem finding so that the code would not be even bigger than what I already posted. If needed I will post it all.
FRONT END WITH ANGULAR
FileFrontEnd interface
export interface FileFrontEnd {
name: string;
path: string;
imageBytes: string;
}
FileFrontEnd service
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { environment } from "src/environments/environment";
import { FileFrontEnd } from "./file";
@Injectable({
providedIn: 'root'
})
export class FileService {
private apiServerUrl = environment.apiBaseUrl;//'http://localhost:8080'
constructor(private http: HttpClient) { }
public getFiles(): Observable<FileFrontEnd[]> {
return this.http.get<FileFrontEnd[]>(`${this.apiServerUrl}/file/all`);
}
}
App Component
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FileFrontEnd } from './file';
import { FileService } from './file.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'file-web-app';
public files!: FileFrontEnd[];
constructor(private fileService: FileService){}
ngOnInit(): void {
this.getFiles();
}
public getFiles(): void {
this.fileService.getFiles().subscribe(
(response: FileFrontEnd[]) => {
this.files = response;
for(let i = 0; i < this.files.length; i++) {
console.log(this.files[i].imageBytes);
}
},
(error: HttpErrorResponse) => {
alert(error.message);
}
);
}
}
App Component HTML
<table>
<tr>
<th>Name</th>
<th>Path</th>
<th>Icon String</th>
</tr>
<tr>
<td style='cursor: pointer; cursor: hand;' (click)="backPath()">..</td>
<td>home path</td>
<td>No Icon String</td>
</tr>
<tr *ngFor="let file of files" style='cursor: pointer; cursor: hand;' (click)="changePath(file.path)">
<td><img src="data:image/png;base64,{{file.imageBytes}}"> {{file.name}}</td>
<td>{{file.path}}</td>
<td>{{file.imageBytes}}</td>
</tr>
</table>
BACKEND IN JAVA
package com.file.web.fileweb;
import org.springframework.util.Base64Utils;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class FileFrontEnd {
private String name;
private String path;
private String imageBytes;
//private Icon imageIcon;
//constructors
//public FileFrontEnd() { }
public FileFrontEnd(String name, String path, String imageBytes) {
this.name = name;
this.path = path;
this.imageBytes = imageBytes;
//this.imageIcon = imageIcon;
}
//getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPath() { return path; }
public void setPath(String path) { this.path = path; }
public String getImageIcon() { return imageBytes; }
public void setImageIcon(String imageBytes) { this.imageBytes = imageBytes; }
//converter from Icon to byte[] to String
public static String convertToBytes(Icon icon) {
BufferedImage img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
icon.paintIcon(null,g2d,0,0);
g2d.dispose();
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
try {
ImageIO.write(img, "png", ios);
// Set a flag to indicate that the write was successful
} finally {
ios.close();
}
byte[] bytes = baos.toByteArray();
//return bytes;
String encodedText = Base64Utils.encodeToString(bytes);
return encodedText;
} catch(IOException ex) {
ex.printStackTrace();
}
return null;
}
}
And this is the GetMapping, where the fileSystem is an object of my calss FileSystem that is needed to get paths and the file icon and it seems to be working fine
@GetMapping("/all")
public ResponseEntity<List<FileFrontEnd>> getAllFiles() {
File[] filesArray = fileSystem.listFiles(fileSystem.getCurrentPath());
//convert... to FileFrontEnd
List<FileFrontEnd> filesFront = new ArrayList<FileFrontEnd>();
for(int i = 0; i < filesArray.length; i++) {
FileFrontEnd f = new FileFrontEnd(filesArray[i].getName(), filesArray[i].getPath(), FileFrontEnd.convertToBytes(fileSystem.getIconImageForPath(filesArray[i])));
filesFront.add(f);
}
return new ResponseEntity<>(filesFront, HttpStatus.OK);
}
Explanation
What this sould do is show an HTML page with a table of files/folders in the currentPath (folder) that I reached with getCurrentPath() in the GetMapping. And what I wanted to achieve is to include also the Icon shown in the file explorer of the pc, but on the page.
Problem
My problem is that the imageBytes in FileFrontEnd seems to be undefined (i 'console.log()'-ged it)
in fact in the HTML page {{file.imageBytes}} doesn't print anything. On the other side the name and path, both strings, work perfectly fine. I thought that suggested the error was in the BackEnd, but I verified that the string FileFrontEnd.convertToBytes(fileSystem.getIconImageForPath(filesArray[i]))
(which is the String conversion of the byte[] conversion of the Icon seen in FileFrontEnd.convertToBytes(Icon icon)) computes what I want it to.
So I thought there might be some kind of error with the imageBytes string during the connection between back and front end, but I could not find any documentation on this. (maybe the length of the string idk)
Is somebody able to help with this?
This is how it looks like, where the standard 'error' icons should be replaced with the pc ones.
