У меня есть файл «create-profile.component.html» на угловом 7, содержащий форму с 4 полями ввода текста, кнопку выбора изображения и кнопку отправки.
Кнопка отправки является единственной с типом = "отправить".
Я использую файл profiles.service.ts для настройки функций для работы с грубыми задачами, которые я внедряю и вызываю в create-profile.component.ts. Я также использую FormGroup для обработки ввода.
Проблема заключается в следующем:
https://i.imgur.com/xF2yOeZ.png
Я заглянул внутрь 'create-profile.component.ts', где указывается ошибка, но я не могу обнаружить никаких проблем. Функция addProfile () внедряется в компонент из-за profileService внутри конструктора. Кроме того, profileService в первую очередь содержит функцию addProfile (). На HTML-разметке я не вижу никаких проблем.
Create-profile.component.ts
export class CreateProfileComponent implements OnInit, OnDestroy {
profile: Profile;
isLoading = false;
form: FormGroup;
profileImagePreview: string;
private mode = 'create';
private profileId: string;
private authStatusSub: Subscription;
constructor(
private profilesService: ProfilesService,
public route: ActivatedRoute,
private authService: AuthService
) {}
ngOnInit() {
this.authStatusSub = this.authService
.getAuthStatusListener()
.subscribe(authStatus => {
this.isLoading = false;
});
this.form = new FormGroup({
name: new FormControl(null, {
validators: [Validators.required, Validators.minLength(1)]
}),
username: new FormControl(null, {
validators: [Validators.required, Validators.minLength(1)]
}),
bio: new FormControl(null, {
validators: [Validators.required]
}),
profileImage: new FormControl(null, {
validators: [Validators.required],
asyncValidators: [mimeType]
}),
});
this.route.paramMap.subscribe((paramMap: ParamMap) => {
if (paramMap.has('profileId')) {
this.mode = 'edit';
this.profileId = paramMap.get('profileId');
this.isLoading = true;
this.profilesService.getProfile(this.profileId).subscribe(profileData => {
this.isLoading = false;
this.profile = {
id: profileData._id,
name: profileData.name,
username: profileData.username,
bio: profileData.bio,
profileImage: profileData.profileImage,
creator: profileData.creator
};
this.form.setValue({
name: this.profile.name,
username: this.profile.username,
bio: this.profile.bio,
profileImage: this.profile.profileImage,
});
});
} else {
this.mode = 'create';
this.profileId = null;
}
});
}
onProfileImagePicked(event: Event) {
const file = (event.target as HTMLInputElement).files[0];
this.form.patchValue({ profileImage: file });
this.form.get('profileImage').updateValueAndValidity();
const reader = new FileReader();
reader.onload = () => {
////////////////// 'as string' could be removed;
this.profileImagePreview = reader.result as string;
};
reader.readAsDataURL(file);
}
onSaveProfile() {
if (this.form.invalid) {
return;
}
this.isLoading = true;
if (this.mode === 'create') {
this.profilesService.addProfile(
this.form.value.name,
this.form.value.username,
this.form.value.bio,
this.form.value.profileImage,
);
} else {
this.profilesService.updateProfile(
this.profileId,
this.form.value.name,
this.form.value.username,
this.form.value.bio,
this.form.value.profileImage,
);
}
this.form.reset();
}
ngOnDestroy() {
this.authStatusSub.unsubscribe();
}
}
profiles.service.ts
@Injectable({
providedIn: 'root'
})
export class ProfilesService {
private profiles: Profile[] = [];
private profilesUpdated = new Subject<{ profiles: Profile[] }>();
constructor(private http: HttpClient, private router: Router) { }
addProfile(name: string, username: string, bio: string, profileImage:
File) {
const profileData = new FormData();
profileData.append('name', name);
profileData.append('username', username);
profileData.append('bio', bio);
profileData.append('profileImage', profileImage);
this.http
.post<{ message: string; profile: Profile; }>(
'http://localhost:3000/api/profiles/',
profileData
)
.subscribe(responseData => {
this.router.navigate(['/']);
});
}
создать-profile.component.html
<mat-card class="mat-elevation-z0 card-border">
<mat-spinner *ngIf="isLoading"></mat-spinner>
<form [formGroup]="form" (submit)="onSaveProfile()" *ngIf="!isLoading">
<mat-form-field>
<input
matInput
type="text"
formControlName="name"
placeholder="Full Name">
<mat-error *ngIf="form.get('name').invalid">Please enter a valid name.</mat-error>
</mat-form-field>
<mat-form-field>
<input
matInput
type="text"
formControlName="username"
placeholder="Username">
<mat-error *ngIf="form.get('username').invalid">Please enter a valid username.</mat-error>
</mat-form-field>
<mat-form-field>
<textarea
matInput
rows="4"
type="text"
formControlName="bio"
placeholder="Bio"></textarea>
<mat-error *ngIf="form.get('bio').invalid">Please enter a few words about yourself.</mat-error>
</mat-form-field>
<div class="porofile-create-buttons-holder">
<button mat-stroked-button type="button" (click)="profileImagePicker.click()">Choose Profile Image</button>
<input type="file" #profileImagePicker (change)="onProfileImagePicked($event)">
<span class="spacer"></span>
<button mat-stroked-button type="submit">Save Profile</button>
</div>
<div class="profile-image-preview" *ngIf="profileImagePreview !== '' && profileImagePreview && form.get('profileImage').valid">
<img [src]="profileImagePreview" [alt]="form.value.username">
</div>
</form>
</mat-card>
Я не ожидаю ошибок. У меня есть буквально схожий компонент и сервис, выполняющий одно и то же для «сообщений», и он прекрасно работает.