我在 Nx Monorepo 中有一个 Angular 应用程序 (v17)。该组件位于我创建的库中。由于某种原因,当我提交表单时,Http 请求不会触发。一切都正常,直到我尝试使用 SwitchMap 将反应式表单的数据流放入请求中。我已经仔细阅读了文档和示例,但似乎无法弄清楚我哪里出了问题。我还应该提到,这是一个 SSR/SSG Angular 应用程序。
export class SignupFormComponent {
http = inject(HttpClient);
fb = inject(FormBuilder);
headers = new HttpHeaders({ 'Content-Type': 'application/json' });
portalId = 'dummy';
formId = 'dummy';
signUpForm = this.fb.group({
firstName: ['', [Validators.required]],
lastName: ['', [Validators.required]],
email: ['', [Validators.required, Validators.email]],
company: ['', [Validators.required]],
});
dataObject$ = this.signUpForm.valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(),
map((val) =>
Object.keys(val).map((key) => ({
objectTypeId: '0-1',
name: key.toLowerCase(),
value: val[key as keyof typeof val],
})),
),
);
req = this.dataObject$.pipe(
switchMap((data) => {
const url = `https://api.hsforms.com/submissions/v3/integration/submit/${this.portalId}/${this.formId}`;
return this.http.post(url, JSON.stringify(data), {
headers: this.headers,
});
}),
);
submitForm() {
return this.req.subscribe(console.log);
}
}
<form [formGroup]="signUpForm" (ngSubmit)="submitForm()">
<label for="first-name" class="text-white">First Name</label>
<input id="first-name" type="text" formControlName="firstName" />
<label for="last-name" class="text-white">Last Name</label>
<input id="last-name" type="text" formControlName="lastName" />
<label for="email" class="text-white">Email</label>
<input id="email" type="text" formControlName="email" />
<label for="company" class="text-white">Company</label>
<input id="company" type="text" formControlName="company" />
<button type="submit">
Join Now
</button>
</form>
当我们在表单初始化期间订阅它时,
valueChanges
是一个不错的选择,因为我们有distinctUntilChanged
,并且提交表单后没有任何值更改,因此永远不会调用POST
,以简化此用例,我们可以使用您编写的相同逻辑手动构造请求对象,然后调用 api!
import { CommonModule } from '@angular/common';
import {
HttpClient,
HttpHeaders,
provideHttpClient,
} from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import {
distinctUntilChanged,
debounceTime,
map,
switchMap,
BehaviorSubject,
} from 'rxjs';
import 'zone.js';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, CommonModule],
template: `
<form [formGroup]="signUpForm" (ngSubmit)="submitForm()">
<label for="first-name" class="text-white">First Name</label>
<input id="first-name" type="text" formControlName="firstName" />
<label for="last-name" class="text-white">Last Name</label>
<input id="last-name" type="text" formControlName="lastName" />
<label for="email" class="text-white">Email</label>
<input id="email" type="text" formControlName="email" />
<label for="company" class="text-white">Company</label>
<input id="company" type="text" formControlName="company" />
<button type="submit">
Join Now
</button>
</form>
`,
})
export class App {
formObjectSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
http = inject(HttpClient);
fb = inject(FormBuilder);
headers = new HttpHeaders({ 'Content-Type': 'application/json' });
portalId = 'dummy';
formId = 'dummy';
signUpForm = this.fb.group({
firstName: ['', [Validators.required]],
lastName: ['', [Validators.required]],
email: ['', [Validators.required, Validators.email]],
company: ['', [Validators.required]],
});
constructData() {
return Object.keys(this.signUpForm.controls).map((key) => {
const val = this.signUpForm.controls;
return {
objectTypeId: '0-1',
name: key.toLowerCase(),
value: val[key as keyof typeof val].value,
};
});
}
submitForm() {
const data = this.constructData();
console.log(data);
const url = `https://api.hsforms.com/submissions/v3/integration/submit/${this.portalId}/${this.formId}`;
return this.http.post(url, JSON.stringify(data), {
headers: this.headers,
});
}
}
bootstrapApplication(App, {
providers: [provideHttpClient()],
});