I'm having trouble trying to figure out how to route a form submission from frontend through a GraphQL mutation and ultimately insert into a SQLite db table.
I've posted my question and code below. Is there any pointers someone could provide?
https://stackoverflow.com/questions/48553675/reactjs-post-with-express-graphql-and-sqlite3
Thanks
If you are on the feature/apollo branch, the general pattern is to use the graphql HOC with a graphql file as input. This will add a mutation function to your component props which you can call to fire your mutation.
Here's an example using ant-design's form lib + Apollo File Uploads to make it interesting + React Apollo
./CoolFormComponent.jsCoolFormComponent
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import { graphql, compose } from 'react-apollo';
import s from './styles.css';
import myMutation from './graphql/myMutation.graphql';
import { Form, Input, Tooltip, Icon, Row, Col, Button, Upload } from 'antd';
const FormItem = Form.Item;
const Dragger = Upload.Dragger;
class CoolFormComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
fileList: [],
};
}
// Validate fields and recieve values from the form after clicking submit
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
this.sendMutation(values);
}
});
}
// Submit the mutation
sendMutation = (values) => {
this.setState({
isLoading: true,
fileList: []
});
this.props.myMutation({
variables: {
name: values.name,
image: this.state.fileList[0] || null
}
})
.then(({ data }) => {
console.log(data.myMutation);
// Reset form fields
this.props.form.resetFields();
// Turn off loading status on submit button
this.setState({
isLoading: false,
});
}).catch((error) => {
// Whoopsie, there was an error
console.log('there was an error sending this mutation', error);
console.log(error);
// Add an error message to the name field
this.props.form.setFields({
name: {
value: values.name,
errors: [new Error(`An error has occured!.`)],
},
});
// Stop the loading status of the submit button
this.setState({
isLoading: false,
});
});
}
render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 8 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 16 },
sm: { span: 16 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 20,
},
sm: {
span: 20,
},
},
};
// Just some props for handling files
const props = {
accept: 'image/*',
action: '/graphql',
onRemove: (file) => {
this.setState(({ fileList }) => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList,
};
});
},
beforeUpload: (file, { target }) => {
this.setState(({ fileList }) => ({
fileList: [...fileList, file],
}));
return false;
},
fileList: this.state.fileList,
};
return (
<Form onSubmit={this.handleSubmit} layout='inline'>
<FormItem
label={(
<span>
{contentType} Name
<Tooltip title='A name field'>
<Icon type="question-circle-o" />
</Tooltip>
</span>
)}
>
{getFieldDecorator('name', {
rules: [{ required: true, message: `Please enter a name!` }],
})(
<Input
spellCheck={false}
/>
)}
</FormItem>
<FormItem
label={(
<span>
File Upload
<Tooltip title={`Upload an image`}>
<Icon type="question-circle-o" />
</Tooltip>
</span>
)}
>
<Upload {...props}>
<Button>
<Icon type="upload" /> Click to Upload
</Button>
</Upload>
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" size="large" loading={this.state.isLoading}>Submit Form</Button>
</FormItem>
</Form>
);
}
}
export default compose(
Form.create(),
withStyles(s),
graphql(myMutation, {
name: 'myMutation'
}),
)(CoolFormComponent);
./graphql/myMutation.graphqlmyMutation.graphql
mutation myMutation($name: String!, $image: Upload){
myMutation(name: $name, image: $image) {
id
name
logoURL
updatedAt
}
}
For a simpler walkthrough just checkout the docs https://www.apollographql.com/docs/react/basics/mutations.html
Hi @ahummel25, @tim-soft's answer is nice example.
If you need real POST endpoint (like form of REST), you should add express route for that and handle this manually, but it is redundant.. You can transform form data to GraphQL request of course, reusing all the auth and quota code if you have..
Great example @tim-soft
Wondering if you have run into any difficulties initializing values within the forms. Did you have to store your queried data into component state? Imo it seems a little excessive to have to parse your response data into a nested structure just to use and design's mapPropsToFields helper.
@bbtran antd's form lib works via HOC, the form values are available via props. You could obviously handle forms whichever way you'd like, I like doing it this way
@tim-soft thanks for the response!
Most helpful comment
If you are on the feature/apollo branch, the general pattern is to use the
graphqlHOC with a graphql file as input. This will add a mutation function to your component props which you can call to fire your mutation.Here's an example using ant-design's form lib + Apollo File Uploads to make it interesting + React Apollo
./CoolFormComponent.jsCoolFormComponent
./graphql/myMutation.graphqlmyMutation.graphql
For a simpler walkthrough just checkout the docs https://www.apollographql.com/docs/react/basics/mutations.html