ASP.NET CORE & Angular (single solution) .NET 5.0 v10.2.0
I have an entity named Course, Course has an Image I copied the functionality from change-profile-picture
Here is my change-course-image-modal.ts
import { IAjaxResponse, TokenService} from 'abp-ng2-module';
import { Component, Injector, ViewChild } from '@angular/core';
import { AppConsts } from '@shared/AppConsts';
import { AppComponentBase } from '@shared/common/app-component-base';
import { CourseServiceProxy, UpdateCourseImageInput } from '@shared/service-proxies/service-proxies';
import { FileUploader, FileUploaderOptions, FileItem } from 'ng2-file-upload';
import { ModalDirective } from 'ngx-bootstrap/modal';
import { finalize } from 'rxjs/operators';
import {ImageCroppedEvent, base64ToFile} from 'ngx-image-cropper';
@Component({
selector: 'changeCourseImageModal',
templateUrl: './change-course-image-modal.component.html'
})
export class ChangeCourseImageModalComponent extends AppComponentBase {
@ViewChild('changeCourseImageModal', {static: true}) modal: ModalDirective;
courseId = 0;
public active = false;
public uploader: FileUploader;
public temporaryPictureUrl: string;
public saving = false;
public maxCourseImageBytesUserFriendlyValue = 5;
private temporaryPictureFileName: string;
private _uploaderOptions: FileUploaderOptions = {};
imageChangedEvent: any = '';
constructor(
injector: Injector,
private _courseService: CourseServiceProxy,
private _tokenService: TokenService
) {
super(injector);
}
initializeModal(courseId: number): void {
this.active = true;
this.temporaryPictureUrl = '';
this.temporaryPictureFileName = '';
this.initFileUploader();
this.courseId = courseId;
}
show(courseId?: number): void {
this.initializeModal(courseId);
this.modal.show();
}
close(): void {
this.active = false;
this.imageChangedEvent = '';
this.uploader.clearQueue();
this.modal.hide();
}
fileChangeEvent(event: any): void {
if (event.target.files[0].size > 5242880) { //5MB
this.message.warn(this.l('CourseImage_Warn_SizeLimit', this.maxCourseImageBytesUserFriendlyValue));
return;
}
this.imageChangedEvent = event;
}
imageCroppedFile(event: ImageCroppedEvent) {
this.uploader.clearQueue();
this.uploader.addToQueue([<File>base64ToFile(event.base64)]);
}
initFileUploader(): void {
this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/Course/UploadCourseImage' });
this._uploaderOptions.autoUpload = false;
this._uploaderOptions.authToken = 'Bearer ' + this._tokenService.getToken();
this._uploaderOptions.removeAfterUpload = true;
this.uploader.onAfterAddingFile = (file) => {
file.withCredentials = false;
};
this.uploader.onBuildItemForm = (fileItem: FileItem, form: any) => {
form.append('FileType', fileItem.file.type);
form.append('FileName', 'CourseImage');
form.append('FileToken', this.guid());
form.append('CourseId', this.courseId);
};
this.uploader.onSuccessItem = (item, response, status) => {
const resp = <IAjaxResponse>JSON.parse(response);
if (resp.success) {
this.updateCourseImage(resp.result.fileToken);
} else {
this.message.error(resp.error.message);
}
};
this.uploader.setOptions(this._uploaderOptions);
}
updateCourseImage(fileToken: string): void {
const input = new UpdateCourseImageInput();
input.fileToken = fileToken;
input.x = 0;
input.y = 0;
input.width = 0;
input.height = 0;
input.courseId = this.courseId;
this.saving = true;
this._courseService.updateCourseImage(input)
.pipe(finalize(() => { this.saving = false; }))
.subscribe(() => {
abp.event.trigger('courseImageChanged');
this.close();
});
}
guid(): string {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
save(): void {
this.uploader.uploadAll();
}
}
And here is my change-course-modal.html
<div appBsModal #changeCourseImageModal="bs-modal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="myLargeModalLabel" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form *ngIf="active" #changeCourseImageModalForm="ngForm" (ngSubmit)="save()">
<div class="modal-header">
<h5 class="modal-title">
<span>{{"ChangeProductPicture" | localize}}</span>
</h5>
<button type="button" class="close" [attr.aria-label]="l('Close')" (click)="close()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<input type="file" (change)="fileChangeEvent($event)" />
<span class="help-block m-b-none">{{"CourseImage_Change_Info" | localize:maxCourseImageBytesUserFriendlyValue}}</span>
</div>
<image-cropper
[imageChangedEvent]="imageChangedEvent"
[maintainAspectRatio]="true"
[aspectRatio]="4 / 4"
[resizeToWidth]="128"
format="png"
(imageCroppedFile)="imageCroppedFile($event)"
></image-cropper>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="close()" [disabled]="saving">{{"Cancel" | localize}}</button>
<button type="submit" class="btn btn-primary" [disabled]="!changeCourseImageModalForm.form.valid || saving"><i class="fa fa-save"></i> <span>{{"Save" | localize}}</span></button>
</div>
</form>
</div>
</div>
</div>
Problem is that when pressing save on the modal after image resize nothing happens,
save(): void {
this.uploader.uploadAll();
}
This gets fired but it doesn't do anyting, i'm not getting any errors. Banging my head on the keyboard several times but without result.
Please advice
3 Answer(s)
-
0
I've tried this approach too, but had the same issue too, I had assumed I'd not understood correctly the process and parked this for later investigation, so I would be interested to see the "correct" way to upload images in this way is.
AJ.
-
0
Found it! So stupid
<image-cropper [imageChangedEvent]="imageChangedEvent" [maintainAspectRatio]="true" [aspectRatio]="4 / 4" [resizeToWidth]="128" format="png" (imageCroppedFile)="imageCroppedFile($event)" ></image-cropper>
(imageCroppedFile)="imageCroppedFile($event)"
should be(imageCropped)="imageCroppedFile($event)"
-
0
Thank you for sharing the solution @rvanwoezik. Sorry that I haven't seen your question at first.