Charly POLY - Senior Software Engineer at
I
Single Page Applications
Front-end development
❤️
State management
Crypto
Offline capabilities
Routing
Rendering
PWA
Forms =
manual and repetitive task
// Render Prop
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import { CustomInputComponent, CustomPasswordComponent } from './common/components';
import { UserService } from './services/UserService';
const Basic = () => (
<Formik
validate={values => {
let errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => UserService.update(values, setSubmitting) }
>
{({ isSubmitting }) => (
<Form>
<Field type="email" name="email" component={CustomInputComponent} />
<ErrorMessage name="email" component="div" />
<Field type="password" name="password" component={CustomPasswordComponent} />
<ErrorMessage name="password" component="div" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
);
export default Basic;
"Forms handle the experience that users have with data"
class Form extends ModuleForm {
fields: FieldsDefinitions = {
id: 'none',
email: 'none',
picture_path: {
type: 'image', transformations: 'h_200,w_200,r_max,c_fill'
},
first_name: 'string*',
last_name: 'string*',
username: 'string*',
job_title: 'string',
company_name: 'string',
language: {
type: 'select*',
component: LanguageSelectView,
valueProperty: 'code',
values: supportedLanguages,
moduleName: 'attachment'
}
};
constructor() {
super('UserForm', 'user');
}
}
HTTP requests
SPA
GraphQL API
GraphQL Schema
Data types
Queries
Mutations
GraphQL API
mutation(user: UserInputType!, company: CompanyInputType) {
create_account(user: $user, company: $company) {
user {
id
}
}
}
mutation
Onboarding
Form
GraphQL API
User model
Company model
introspection
query
GraphQL API
{
"name": "createAccount",
"__typename": "__Field",
"isDeprecated": false,
"deprecationReason": null,
"args": [
{
"name": "user",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "InputType",
"name": "UserInputType",
"ofType": null,
"__typename": "__Type"
},
"__typename": "__Type"
},
"defaultValue": null,
"__typename": "__InputValue"
},
// ...
}
introspection
query
GraphQL API
You can create an Account by providing
a mandatory User type and
an optional Company type
Mutation =
similar to Form UI
Mutation name =
fields + requirements
<Frontier mutation={mutation} client={client} initialValues={{ user: { email: 'hello@charlypoly.com ' } }}>
{
({ state, modifiers, form }) => {
return (
<form onSubmit={modifiers.save}>
<h2>Create a user</h2>
<p>
<label htmlFor="name">Name*</label> <br />
<input
type="text"
name="name"
value={state.values.user.name} onChange={modifiers.user.name.change}
/>
{
state.errors.user && state.errors.user.name &&
<p>
Error: "{state.errors.user.name}"
</p>
}
</p>
<p>
<input type="submit" value="Save" />
</p>
</form>
)
}
}
</Frontier>
GraphQL
final-form
Apollo GraphQL
Fields definitions
Form state
Save data
const mutation = gql`
mutation ($user: UserInputType!) {
createUser(user: $user) {
...User
}
}
`;
<Frontier mutation={mutation} client={client} uiKit={ApplicationUIkit} />
<Frontier client={client} mutation={mutation} uiKit={ApplicationUIkit}>
{
({ form, kit }) => {
return (
<form className='ui form' onSubmit={(e) => { e.preventDefault(); form.submit(); }}>
<div>
{kit.company()}
</div>
<Message
info
header='Is my company already registered?'
list={[
'If your company is already registred under a Business plan, please do register using the Business form',
]}
/>
<br />
<br />
<div>
{kit.email()}
</div>
<br />
<div>
{kit.firstname()}
</div>
<br />
<div>
{kit.lastname()}
</div>
<p>
<input type="submit" value="Save" className="ui button" />
</p>
</form>
)
}
}
</Frontier>
How to:
Frontier Core
Frontier React
Frontier Data
- Apollo GraphQL
- ajv
- final-form
Thank you!