I am in the final stages of developing an application that is similar to https://www.ethereum.org/crowdsale, however, when I click on the create button, my Metamask modal is not popping up to ask me if I want to approve or reject the transaction.
This is my pages/campaigns/requests/new.js
file where this is all taking place:
import React, { Component } from "react";
import { Form, Button, Message, Input } from "semantic-ui-react";
import Campaign from "../../../ethereum/campaign";
import web3 from "../../../ethereum/web3";
import { Link, Router } from "../../../routes";
import Layout from "../../../components/Layout";
class RequestNew extends Component {
state = {
value: "",
description: "",
recipient: ""
};
static async getInitialProps(props) {
const address = props.query;
return { address };
}
onSubmit = async event => {
event.preventDefault();
const campaign = Campaign(this.props.address);
const { description, value, recipient } = this.state;
try {
const accounts = await web3.eth.getAccounts();
await campaign.methods
.createRequest(description, web3.utils.toWei(value, "ether"), recipient)
.send({ from: accounts[0] });
} catch (err) {}
};
render() {
return (
<Layout>
<h3>Create a Request</h3>
<Form onSubmit={this.onSubmit}>
<Form.Field>
<label>Description</label>
<Input
value={this.state.description}
onChange={event =>
this.setState({ description: event.target.value })
}
/>
</Form.Field>
<Form.Field>
<label>Value in Ether</label>
<Input
value={this.state.value}
onChange={event => this.setState({ value: event.target.value })}
/>
</Form.Field>
<Form.Field>
<label>Recipient</label>
<Input
value={this.state.recipient}
onChange={event =>
this.setState({ recipient: event.target.value })
}
/>
</Form.Field>
<Button primary>Create!</Button>
</Form>
</Layout>
);
}
}
export default RequestNew;
This is my ethereum/campaign.js
file:
import web3 from './web3';
import Campaign from './build/Campaign.json';
export default address => {
return new web3.eth.Contract(JSON.parse(Campaign.interface), address);
};
This is my ethereum/web3.js
file:
import Web3 from 'web3';
let web3;
if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
// we are in the browser and metamask is running
web3 = new Web3(window.web3.currentProvider);
} else {
// we are on the server *OR* the user is not running metamask
const provider = new Web3.providers.HttpProvider(
'https://rinkeby.infura.io/abc123'
);
web3 = new Web3(provider);
}
export default web3;
Can anybody see where I missed a step? I am not getting any errors of any sort, just not getting the behavior thats expected when creating a transaction with the Create button which is for Metamask modal to pop up.
So I decided to add some error handling in my try/catch
block:
onSubmit = async event => {
event.preventDefault();
const campaign = Campaign(this.props.address);
const { description, value, recipient } = this.state;
this.setState({ loading: true, errorMessage: "" });
try {
const accounts = await web3.eth.getAccounts();
await campaign.methods
.createRequest(description, web3.utils.toWei(value, "ether"), recipient)
.send({ from: accounts[0] });
Router.pushRoute(`/campaigns/${this.props.address}/requests`);
} catch (err) {
this.setState({ errorMessage: err.message });
}
this.setState({ loading: false });
};
render() {
return (
<Layout>
<h3>Create a Request</h3>
<Form onSubmit={this.onSubmit} error={!!this.state.errorMessage}>
<Form.Field>
<label>Description</label>
<Input
value={this.state.description}
onChange={event =>
this.setState({ description: event.target.value })
}
/>
</Form.Field>
<Form.Field>
<label>Value in Ether</label>
<Input
value={this.state.value}
onChange={event => this.setState({ value: event.target.value })}
/>
</Form.Field>
<Form.Field>
<label>Recipient</label>
<Input
value={this.state.recipient}
onChange={event =>
this.setState({ recipient: event.target.value })
}
/>
</Form.Field>
And sure enough when I tried creating a request again I was able to see the following error message render to the screen:
This contract object doesn't have address set yet, please set an address first
I am not sure how I do not have an address set yet on this contract object.