Working validation from the server using CallOuts

This commit is contained in:
Belen Curcio
2018-08-16 16:21:52 -03:00
parent e4ebb2553f
commit 94ad23ce9b
10 changed files with 50 additions and 31 deletions
+7 -3
View File
@@ -28,20 +28,24 @@ interface FormProps {
export interface SignInForm {
onSubmit: OnSubmit<FormProps>;
setView: (view: View) => void;
errorMessage: string;
error: string | null;
}
const SignIn: StatelessComponent<SignInForm> = props => {
console.log(props);
return (
<Form onSubmit={props.onSubmit}>
{({ handleSubmit, submitting }) => (
<form autoComplete="off" onSubmit={handleSubmit}>
{props.errorMessage && <CallOut>{props.errorMessage}</CallOut>}
<Flex itemGutter direction="column" className={styles.root}>
<Typography variant="heading1" align="center">
Sign in to join the conversation
</Typography>
{props.error && (
<CallOut color="error" fullWidth>
{props.error}
</CallOut>
)}
<Field
name="email"
validate={composeValidators(required, validateEmail)}
+7 -3
View File
@@ -34,13 +34,13 @@ interface FormProps {
export interface SignUpForm {
onSubmit: OnSubmit<FormProps>;
setView: (view: View) => void;
errorMessage: string;
error: string | null;
}
const SignUp: StatelessComponent<SignUpForm> = props => {
return (
<Form onSubmit={props.onSubmit}>
{props.errorMessage && <CallOut>{props.errorMessage}</CallOut>}
{!!props.error && <CallOut>{props.error}</CallOut>}
{({ handleSubmit, submitting }) => (
<form autoComplete="off" onSubmit={handleSubmit}>
<Flex itemGutter direction="column" className={styles.root}>
@@ -48,7 +48,11 @@ const SignUp: StatelessComponent<SignUpForm> = props => {
<Typography variant="heading1" align="center">
Sign up to join the conversation
</Typography>
{props.error && (
<CallOut color="error" fullWidth>
{props.error}
</CallOut>
)}
<Field
name="email"
validate={composeValidators(required, validateEmail)}
@@ -1,5 +1,6 @@
import React, { Component } from "react";
import { BadUserInputError } from "talk-framework/lib/errors";
import SignIn, { SignInForm } from "../components/SignIn";
import {
SetViewMutation,
@@ -14,7 +15,7 @@ interface SignInContainerProps {
}
interface SignUpContainerState {
errorMessage: string;
error: string | null;
}
export type View = "SIGN_UP" | "FORGOT_PASSWORD";
@@ -23,7 +24,7 @@ class SignInContainer extends Component<
SignInContainerProps,
SignUpContainerState
> {
public state = { errorMessage: "" };
public state = { error: null };
private setView = (view: View) => {
this.props.setView({
view,
@@ -31,15 +32,13 @@ class SignInContainer extends Component<
};
private onSubmit: SignInForm["onSubmit"] = async (input, form) => {
try {
const res = await this.props.signIn(input);
console.log(res);
// form.reset();
await this.props.signIn(input);
form.reset();
} catch (error) {
this.setState({ error: error.message });
if (error instanceof BadUserInputError) {
return error.invalidArgsLocalized;
}
console.log(error);
this.setState({ errorMessage: `Error: ${error}` });
// tslint:disable-next-line:no-console
console.error(error);
}
@@ -50,7 +49,7 @@ class SignInContainer extends Component<
<SignIn
onSubmit={this.onSubmit}
setView={this.setView}
errorMessage={this.state.errorMessage}
error={this.state.error}
/>
);
}
@@ -15,7 +15,7 @@ interface SignUpContainerProps {
}
interface SignUpContainerState {
errorMessage: string;
error: string | null;
}
export type View = "SIGN_IN";
@@ -24,7 +24,7 @@ class SignUpContainer extends Component<
SignUpContainerProps,
SignUpContainerState
> {
public state = { errorMessage: "" };
public state = { error: "" };
private setView = (view: View) => {
this.props.setView({
view,
@@ -32,15 +32,13 @@ class SignUpContainer extends Component<
};
private onSubmit: SignUpForm["onSubmit"] = async (input, form) => {
try {
const res = await this.props.signUp(input);
console.log("response", res);
await this.props.signUp(input);
form.reset();
} catch (error) {
console.log("error", error);
this.setState({ error: error.message });
if (error instanceof BadUserInputError) {
return error.invalidArgsLocalized;
}
this.setState({ errorMessage: `Something ${error}` });
// tslint:disable-next-line:no-console
console.error(error);
}
@@ -51,7 +49,7 @@ class SignUpContainer extends Component<
<SignUp
onSubmit={this.onSubmit}
setView={this.setView}
errorMessage={this.state.errorMessage}
error={this.state.error}
/>
);
}
@@ -17,6 +17,7 @@ export async function commit(
window.close();
} catch (err) {
postMessage.send("authError", err.toString(), window.opener);
throw Error(err.message);
}
}
@@ -11,10 +11,14 @@ export async function commit(
input: SignOffInput,
{ rest, localStorage }: TalkContext
) {
await signOff(rest, input);
// tslint:disable-next-line:no-console
console.log("Signing off");
localStorage.removeItem("authToken");
try {
await signOff(rest, input);
localStorage.removeItem("authToken");
} catch (error) {
localStorage.removeItem("authToken");
// tslint:disable-next-line:no-console
console.error("error", error);
}
}
export const withSignOffMutation = createMutationContainer("signOff", commit);
@@ -17,6 +17,7 @@ export async function commit(
window.close();
} catch (err) {
postMessage.send("authError", err.toString(), window.opener);
throw Error(err.toString());
}
}
@@ -0,0 +1,4 @@
export interface ExceptionError {
message: string;
stack: string;
}
@@ -2,4 +2,6 @@ export { default as NetworkError } from "./networkError";
export { default as UnknownServerError } from "./unknownServerError";
export { default as BadUserInputError } from "./badUserInputError";
export { default as GraphQLError } from "./graphqlError";
export { default as ExceptionError } from "./exceptionError";
export * from "./graphqlError";
+8 -6
View File
@@ -18,6 +18,11 @@ const buildOptions = (inputOptions: RequestInit = {}) => {
};
const handleResp = async (res: Response) => {
if (res.status === 404) {
const response = await res.text();
throw new Error(response);
}
if (!res.ok) {
const response = await res.json();
throw new Error(response.error);
@@ -41,7 +46,7 @@ export class RestClient {
this.tokenGetter = tokenGetter;
}
public fetch<T>(path: string, options: PartialRequestInit): Promise<T> {
public async fetch<T>(path: string, options: PartialRequestInit): Promise<T> {
let opts = options;
if (this.tokenGetter) {
opts = merge({}, options, {
@@ -50,10 +55,7 @@ export class RestClient {
},
});
}
return fetch(`${this.uri}${path}`, buildOptions(opts))
.then(handleResp)
.catch(err => {
throw Error(err);
});
const response = await fetch(`${this.uri}${path}`, buildOptions(opts));
return handleResp(response);
}
}