The scenario is simple. Use a form to upload an image and if it is successfully uploaded, refresh a photogallery. I use angular6 and ng-carousel. All the system is locally set in my windows 10 laptop.
The form gets uploaded, the text data are saved on the database and the image is saved in a file in node 8.11.1. I save the image in the src/assets/images
. I can see the changes and I get no errors while uploading.
But, after the upload, I try to use the URL of the new image to add it as the last image in the carousel and all I get is a 404 error. The URL is like http://localhost:4200/assets/images/unsplash.jpg
The URL is valid, the image is there and all the other carousel images use the same URL. But, the new image has a 404 error. I have to recompile the angular app to see the image. Not just refresh the page, recompile the whole app.
I dont know how to fix this. I tried using a File object or the HTML5 FileReader API on the front end and not depend on creating a URL after image upload. But they dont have a URL and the ng-carousel needs a URL like /assets/images/img.jpg
to work. In order to use some kind of URL, I also tried to get the temporary URL from node and return it back to the front-end, but since it is a temp
folder URL, browser wont let me use it. I also tried to use createObjectURL
but is not supported in all browsers. I also tried to perform a GET
after the image is saved and get all the images names from the database, to loop them again and feed the carousel template once again. Nothing. Still a 404 error. I have to recompile the app.
What is happening? Is this a angular 6 issue? Security restriction? Please help me fix this, I dont know how to deal with it anymore.
Outline of code.
the form
<form *ngIf="pointPartsActive" [formGroup]="imageUpload" (ngSubmit)="imageUploadSubmitted($event.target)" >
<input type="file" (change)='imageChange($event)' #imageInput id="imageInput" name = 'imageInput' accept=".png, .jpg, .jpeg, .gif" formControlName="imageInput" >
<input type="text" formControlName="imageName" name='imageName' placeholder="name" >
<button type="submit" >Submit</button>
</form>
html carousel template, add custom html to also delete an image on the spot.
<ngb-carousel #carousel *ngIf="images" (slide)="onSlide($event)">
<ng-template ngbSlide *ngFor="let im of images; let i = index" id="{{im.id}}">
<img src='../assets/images/{{im.name}}' >
<div class='carousel-img-details'>
<button type="button" (click)='deletepic(im.photoId)'>delete</button>
</div>
</ng-template>
</ngb-carousel>
form submit
imageUploadSubmitted(form){
let formData = new FormData(form);
let eb =null;
this.http.post('http://localhost:3000/cms/upload',formData,{reportProgress:true,observe:'events'}).subscribe(
event=>{
if(event.type === HttpEventType.Response){
eb = event.body;
if(eb.success){
this.imageUpload.reset();
this.addpic(eb.data);
}
}
});
}
after successful form submit, update the array that feeds the carousel. Its a simple array of json objects like [{'id':1,'name':'James'},{'id':2,'name':'Nolan'}]
and feeds the carousel via ngFor
.
addpic(data){
let slide = null;
this.images.push({
'photoId':Number(data.id)
'id': this.images.length,
'name': data.name
});
//get the id of the last slide and go there :
setTimeout(() => {
slide = this.images[this.images.length-1].id;
this.carousel.select(slide);
});
this.images = this.images.slice(); //try to "refresh" array itself
}
The code logic in stackblitz
Thanks