Chapter 05 (Invoice App Integrating with GraphQL server using Relay) - Intuit-London/imperial-react-workshop GitHub Wiki
https://github.com/Intuit-London/imperial-react-workshop/wiki/Chapter-03-(Invoice-App---Static-Data)https://github.com/Intuit-London/imperial-react-workshop/wiki/Chapter-04-(Understanding-GraphQL)
- npm install --save react-relay
- npm install --save-dev babel-relay-plugin
- npm install --save-dev babel-preset-stage-0
- npm install --save-dev babel-plugin-transform-class-properties
- Download
schema.jsonfrom Graphql server and copy it tobuild-utils/schema.jsoncurl -X GET http://localhost:8080/introspection > /tmp/schema.json - Create
babelRelayPlugin.jsunderbuild-utilsfolder
var getbabelRelayPlugin = require('babel-relay-plugin');
var schema = require('./schema.json');
module.exports = getbabelRelayPlugin(schema.data);
- Update
.babelrcfile
{
"presets": [
"react",
"es2015",
"stage-0",
{
"plugins": ["./build-utils/babelRelayPlugin"]
}
],
"plugins":["transform-class-properties"]
}
- Enhance
InvoiceRowcomponent as below
import Relay from "react-relay";
export default Relay.createContainer(InvoiceRow, {
fragments: {
invoice: () => Relay.QL`
fragment on Invoice {
id,
number,
creationDate,
paid,
totalAmount,
customer {
businessName
}
}`
}
});
- Enhance
InvoiceListcomponent as below
import Relay from "react-relay";
export default Relay.createContainer(InvoiceList, {
fragments: {
invoices: () => Relay.QL`
fragment on Invoice @relay(plural: true) {
${InvoiceRow.getFragment("invoice")}
}`
}
});
- Enhance
InvoiceSummarycomponent as below
import Relay from "react-relay";
- Enhance
InvoiceCreatecomponent as below
import Relay from "react-relay";
- Enhance
InvoiceAppcomponent as below
import Relay from "react-relay";
return (
<div>
<AppHeader createInvoice = {this.setCreateInvoice.bind(this)} listInvoice = {this.setListInvoice.bind(this)}/>
<InvoiceSummary user={this.props.user}/>
{this.state.isCreateInvoice ? <InvoiceCreate/> : <InvoiceList invoices={this.props.user.invoices}/> }
</div>
);
export default Relay.createContainer(InvoiceApp, {
fragments: {
user: () => Relay.QL`
fragment on User {
firstName,
invoices {
${InvoiceList.getFragment("invoices")}
}
}`
}
});
- Use
Relay.Rendererto create ourInvoiceAppRenderer.js
import React, {PropTypes} from "react";
import Relay from "react-relay";
import InvoiceRoute from "../routes/InvoiceRoute";
import InvoiceApp from "./InvoiceApp";
class InvoiceAppRenderer extends React.Component {
constructor(props) {
super(props);
this.renderWidget = this.renderWidget.bind(this);
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://localhost:8080/graphql')
);
}
renderWidget(data) {
if (data.error) {
return (<div>Error</div>);
} else if (data.props) {
return (<InvoiceApp user={data.props.user[0]}/>);
}
return (<div>Loading</div>)
}
render() {
return (
<Relay.Renderer
Container={InvoiceApp}
queryConfig={new InvoiceRoute()}
environment={Relay.Store}
render={this.renderWidget}
forceFetch={true}
/>
);
}
}
export default InvoiceAppRenderer;
- Create
InvoiceRoute.jsundersrc/routes/
import Relay from "react-relay";
export default class InvoiceRoute extends Relay.Route {
static routeName = "invoiceRoute";
static queries = {
user: () => Relay.QL `
query {
users (id: ["L1VzZXI6dXNlci0x"])
}
`
};
}
- Imports
import InvoiceAppRenderer from './app/InvoiceAppRenderer';
- Remove dependency on the static json list. (Remove import invoiceList from './data/invoiceList)
- Change the InvoiceAppFactory to use InvoiceAppRenderer
var InvoiceAppFactory = React.createFactory(InvoiceAppRenderer);
- Build the project (npm run build)
- npm run dev
- Refresh your browser (http://localhost:8080) Ensure that the Graphql server is running at http://localhost:8080
- Mutation for Create Invoice
import Relay from "react-relay";
export default class CreateInvoiceMutation extends Relay.Mutation {
getMutation() {
return Relay.QL `mutation createInvoice{createInvoice}`;
}
getVariables() {
let data = {
invoice: this.props
};
data.invoice.user = {"id" : "L1VzZXI6dXNlci0x"};
return data;
}
getFatQuery() {
return Relay.QL `
fragment on User {
invoices {
number
}
}
`;
}
getConfigs() {
return [
{
type: "REQUIRED_CHILDREN",
children: [Relay.QL `
fragment on CreateInvoicePayload {
invoice {
user {
id
},
number,
totalAmount
}
}
`]
}
];
}
}
-
Import
CreateInvoiceMutation.jsintoInvoiceCreatecomponentimport CreateInvoiceMutation from '../mutations/CreateInvoiceMutation'; -
Create function and associate with the button
click.
<button type="button" className="btn btn-primary" onClick={this.createInvoice.bind(this)}>Save</button>
createInvoice = () => {
const mutation = new CreateInvoiceMutation({
number : this.invoiceNumber.value,
creationDate : this.invoiceDate.value,
paid : this.invoicePaid.checked,
customer : {
businessName: this.customername.value,
id: "12431"
},
totalAmount: this.invoiceAmount.value
});
Relay.Store.commitUpdate(mutation, {onFailure: function() {
alert('invoice creation failed');
}, onSuccess: function() {
alert('invoice created');
}});
}