Skip to content

Commit

Permalink
fix(router): properly parse json response in the FormAction
Browse files Browse the repository at this point in the history
  • Loading branch information
milosdanilov committed Feb 11, 2025
1 parent b104183 commit b5ee12b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 25 deletions.
16 changes: 16 additions & 0 deletions apps/analog-app-e2e-cypress/src/e2e/newsletter.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as newsletter from '../support/newsletter.po';

describe('Newsletter', () => {
it(`Given the user has filled in their email
When the "Submit" button is clicked
Then the user has sign up for the newsletter`, () => {
const email = '[email protected]';
cy.visit('/newsletter');
newsletter.typeEmail(email);

newsletter.submit();
newsletter
.getSubmitMessage()
.should('have.text', `Thanks for signing up, ${email}!`);
});
});
6 changes: 6 additions & 0 deletions apps/analog-app-e2e-cypress/src/support/newsletter.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const typeEmail = (email: string) =>
cy.get('input[name="email"]').type(email);

export const submit = () => cy.contains('button', /submit/i).click();

export const getSubmitMessage = () => cy.get('#signup-message');
47 changes: 26 additions & 21 deletions apps/analog-app/src/app/pages/newsletter.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Component, signal } from '@angular/core';

import { FormAction } from '@analogjs/router';

import { type NewsletterSubmitResponse } from './newsletter.server';

type FormErrors =
| {
email?: string;
Expand All @@ -15,34 +17,37 @@ type FormErrors =
template: `
<h3>Newsletter Signup</h3>
@if (!signedUp()) {
<form
method="post"
(onSuccess)="onSuccess()"
(onError)="onError($any($event))"
(onStateChange)="errors.set(undefined)"
>
<div>
<label for="email"> Email </label>
<input type="email" name="email" />
@if (signedUpEmail()) {
<div id="signup-message">
Thanks for signing up, {{ signedUpEmail() }}!
</div>
<button class="button" type="submit">Submit</button>
</form>
@if (errors()?.email) {
<p>{{ errors()?.email }}</p>
} } @else {
<div>Thanks for signing up!</div>
} @else {
<form
method="post"
(onSuccess)="onSuccess($any($event))"
(onError)="onError($any($event))"
(onStateChange)="errors.set(undefined)"
>
<div>
<label for="email"> Email </label>
<input type="email" name="email" />
</div>
<button class="button" type="submit">Submit</button>
</form>
@if (errors()?.email) {
<p>{{ errors()?.email }}</p>
}
}
`,
})
export default class NewsletterComponent {
signedUp = signal(false);
signedUpEmail = signal('');
errors = signal<FormErrors>(undefined);

onSuccess() {
this.signedUp.set(true);
onSuccess(res: NewsletterSubmitResponse) {
this.signedUpEmail.set(res.email);
}

onError(result?: FormErrors) {
Expand Down
9 changes: 6 additions & 3 deletions apps/analog-app/src/app/pages/newsletter.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import {
} from '@analogjs/router/server/actions';
import { readFormData } from 'h3';

export type NewsletterSubmitResponse = {
type: 'success';
email: string;
};

export function load() {
return {
loaded: true,
Expand All @@ -24,7 +29,5 @@ export async function action({ event }: PageServerAction) {
return redirect('/');
}

console.log({ email: body.get('email') });

return json({ type: 'success' });
return json<NewsletterSubmitResponse>({ type: 'success', email });
}
9 changes: 8 additions & 1 deletion packages/router/src/lib/form-action.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class FormAction {
const redirectUrl = new URL(res.url).pathname;
this.state.emit('redirect');
this.router.navigate([redirectUrl]);
} else if (res.headers.get('Content-type') === 'application/json') {
} else if (this._isJSON(res.headers.get('Content-type'))) {
res.json().then((result) => {
this.onSuccess.emit(result);
this.state.emit('success');
Expand Down Expand Up @@ -95,4 +95,11 @@ export class FormAction {

return `/api/_analog/pages${window.location.pathname}`;
}

private _isJSON(contentType: string | null): boolean {
const mime = contentType ? contentType.split(';') : [];
const essence = mime[0];

return essence === 'application/json';
}
}

0 comments on commit b5ee12b

Please sign in to comment.