Как решить «Отмена отправки формы, потому что форма не связана» в Angular7? - PullRequest
0 голосов
/ 22 мая 2019

У меня есть файл «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>

Я не ожидаю ошибок. У меня есть буквально схожий компонент и сервис, выполняющий одно и то же для «сообщений», и он прекрасно работает.

1 Ответ

0 голосов
/ 22 мая 2019

Проблема заключалась в ошибке прописной буквы в верхнем регистре внутри контроллера 'profile' моего экспресс-бэкэнда.Мне пришлось перепроверить весь код, связанный с «профилем» на сервере, чтобы понять это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...