<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam</title>
    <description>The latest articles on DEV Community by Sam (@samcracker).</description>
    <link>https://dev.to/samcracker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F353642%2Fe8128c1a-13d3-4ec1-9719-8b667fe55dd5.jpeg</url>
      <title>DEV Community: Sam</title>
      <link>https://dev.to/samcracker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samcracker"/>
    <language>en</language>
    <item>
      <title>Getting error while calling the function of ContractManager in HeaderMenu</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Sun, 22 Mar 2020 20:54:48 +0000</pubDate>
      <link>https://dev.to/samcracker/getting-error-while-calling-the-function-of-contractmanager-in-headermenu-1d97</link>
      <guid>https://dev.to/samcracker/getting-error-while-calling-the-function-of-contractmanager-in-headermenu-1d97</guid>
      <description>&lt;p&gt;&lt;strong&gt;CodeSandBox:&lt;/strong&gt;&lt;a href="https://codesandbox.io/s/funny-moon-krrsj"&gt;https://codesandbox.io/s/funny-moon-krrsj&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;HeaderMenu.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {Component} from 'react';
import {
    Menu,
    Container,
    Button,
    Label,
    Loader,
    List,
    Image,
    Icon,
    Dropdown
} from 'semantic-ui-react';
import Head from 'next/head';
import web3 from '../ethereum/web3';
import Constant from '../support/Constant';
import Config from '../support/Config';
import appDispatcher from '../core/AppDispatcher';
import contractManager from '../core/ContractManager';

class HeaderMenu extends Component {
    constructor(props) {
        super(props);
        this.account = props.account;
        this.contractManager = contractManager;
        // console.log(contractManager);
        this.transactionDispatcher = props.transactionDispatcher;
        this.state = {address: "", balance: "", name: "", 
            avatarUrl: "", isLoading: true, isJoinButtonLoading: false, 
            isJoined: false, numPendingTx: 0};
        this.reloadCount = 0;
    }
    clearAllData = () =&amp;gt; {
        window.localStorage.clear();
    }

    componentDidMount() {
        if (this.account) {
            this.getAccountInfo();
            appDispatcher.register((payload) =&amp;gt; {
                if (payload.action == Constant.EVENT.ACCOUNT_BALANCE_UPDATED) {
                    this.setState({balance: this.account.balance});
                } else if (payload.action == Constant.EVENT.ACCOUNT_INFO_UPDATED) {
                    this.setState({name: payload.profile.name, avatarUrl: payload.profile.avatarUrl, isJoined: payload.profile.isJoined});
                } 
            });
            this.transactionDispatcher.register((payload) =&amp;gt; {
                if (payload.action == Constant.EVENT.PENDING_TRANSACTION_UPDATED) {
                    this.setState({numPendingTx: payload.numPendingTx});
                }
            });
        }
    }

    getAccountInfo = () =&amp;gt; {
        var address = this.account.getAddress();
        if (address) {
            this.setState({address: address, balance: this.account.balance, isLoading: false, isJoined: this.account.isJoined});
        } else {
            if (this.reloadCount == 1) {
                this.setState({isLoading: false});
            } else {
                this.reloadCount++;
                setTimeout(this.getAccountInfo, 800);
            }
        }
    }

    handleDropdownClicked = (event, data) =&amp;gt; {
        if (data.name == 'updateProfile') {
            appDispatcher.dispatch({
                action: Constant.ACTION.OPEN_UPDATE_PROFILE
            });
        } else if (data.name == 'logOutItem') {
            this.clearAllData();
            window.location.reload();
        } else if (data.name == 'settingsItem') {
            appDispatcher.dispatch({
                action: Constant.ACTION.OPEN_SETTINGS_MODAL
            })
        } 
         else if (data.name == 'changeEthNetwork') {
            if (data.networkid != Config.ENV.EthNetworkId) {
                Config.ENV.EthNetworkId = data.networkid;
                this.removeNetworkDependentData();
                window.location.reload();
            }
        }
    }

    removeNetworkDependentData = () =&amp;gt; {
        this.account.storageManager.removeNetworkDependentData();
    }

    handleJoinClicked = () =&amp;gt; {
        var publicKeyBuffer = this.account.getPublicKeyBuffer();
        this.contractManager.joinContract(publicKeyBuffer, (resultEvent) =&amp;gt; {
            if (resultEvent == Constant.EVENT.ON_REJECTED || resultEvent == Constant.EVENT.ON_ERROR) {
                this.setState({isJoinButtonLoading: false});
            } else if (resultEvent == Constant.EVENT.ON_RECEIPT) {
                window.location.reload();
            }
        });
        this.setState({isJoinButtonLoading: true});
    }

    handleImportPrivateKeyClicked = () =&amp;gt; {
        appDispatcher.dispatch({
            action: Constant.ACTION.OPEN_PRIVATE_KEY_MODAL
        });
    }

    render() {
        var accountInfo = (&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;);

        if (this.account) {
            if (this.state.isLoading == false) {
                if (this.state.address) {
                    var addressExplorerUrl = Config.ENV.ExplorerUrl + 'address/' + this.state.address;
                    var dropdownTrigger;

                    if (this.state.avatarUrl) { 
                        dropdownTrigger = (
                            &amp;lt;span&amp;gt;&amp;lt;Image src={this.state.avatarUrl} avatar/&amp;gt;{ this.state.name ? this.state.name : this.state.address.substr(0,10)}&amp;lt;/span&amp;gt;
                        );
                    } else {
                        dropdownTrigger = (
                            &amp;lt;span&amp;gt;&amp;lt;Icon name='user' size='large'/&amp;gt;{ this.state.name ? this.state.name : this.state.address.substr(0,10)}&amp;lt;/span&amp;gt;
                        );
                    }

                    var networkItems = [];
                    for (var i=0;i&amp;lt;Config.NETWORK_LIST.length;i++) {
                        networkItems.push(
                            &amp;lt;Dropdown.Item key={'networkItem' + i} networkid={Config.NETWORK_LIST[i].id} name='changeEthNetwork' onClick={this.handleDropdownClicked}&amp;gt;
                                {Config.NETWORK_LIST[i].name}
                            &amp;lt;/Dropdown.Item&amp;gt;
                        );
                    }

                    var memberInfo;
                    if (this.account.isJoined) {
                        memberInfo = (
                            &amp;lt;Dropdown item trigger={dropdownTrigger}&amp;gt;
                                &amp;lt;Dropdown.Menu&amp;gt;
                                    &amp;lt;Dropdown.Item name='updateProfile' onClick={this.handleDropdownClicked}&amp;gt;
                                        &amp;lt;Icon name='write'/&amp;gt;Update profile
                                    &amp;lt;/Dropdown.Item&amp;gt;
                                    &amp;lt;Dropdown.Item name='settingsItem' onClick={this.handleDropdownClicked}&amp;gt;
                                        &amp;lt;Icon name='settings'/&amp;gt;Settings
                                    &amp;lt;/Dropdown.Item&amp;gt;
                                    &amp;lt;Dropdown.Item name='logOutItem' onClick={this.handleDropdownClicked}&amp;gt;
                                        &amp;lt;Icon name='log out'/&amp;gt;Log out
                                    &amp;lt;/Dropdown.Item&amp;gt;
                                &amp;lt;/Dropdown.Menu&amp;gt;
                            &amp;lt;/Dropdown&amp;gt;
                        );
                    } else {
                        memberInfo = (
                            &amp;lt;Button color='orange' onClick={this.handleJoinClicked} 
                                loading={this.state.isJoinButtonLoading} 
                                disabled={this.state.isJoinButtonLoading}&amp;gt;Join {Constant.APP_NAME}&amp;lt;/Button&amp;gt;
                        );
                    }

                    var pendingTxItem;
                    if (this.state.numPendingTx &amp;gt; 0) {
                        pendingTxItem = (
                            &amp;lt;Label as='a' color='yellow' href={addressExplorerUrl} target='_blank'&amp;gt;
                                &amp;lt;Icon name='spinner' loading/&amp;gt;
                                {this.state.numPendingTx} pending tx
                            &amp;lt;/Label&amp;gt;
                        );
                    }

                    accountInfo = (
                        &amp;lt;Menu.Menu position='right'&amp;gt;
                            &amp;lt;Menu.Item&amp;gt;
                            &amp;lt;Dropdown item text={Config.ENV.NetworkName}&amp;gt;
                                    &amp;lt;Dropdown.Menu&amp;gt;
                                        {networkItems}
                                    &amp;lt;/Dropdown.Menu&amp;gt;
                                &amp;lt;/Dropdown&amp;gt;
                            &amp;lt;/Menu.Item&amp;gt;
                            &amp;lt;Menu.Item&amp;gt;
                                &amp;lt;List&amp;gt;
                                &amp;lt;List.Item&amp;gt;
                                    &amp;lt;a href={addressExplorerUrl} target='_blank'&amp;gt;
                                        {this.state.address}
                                    &amp;lt;/a&amp;gt;
                                &amp;lt;/List.Item&amp;gt;
                                &amp;lt;List.Item&amp;gt;
                                    Balance: &amp;lt;Label as='a' href={addressExplorerUrl} target='_blank' color='orange'&amp;gt;{parseFloat(web3.utils.fromWei("" +this.state.balance, 'ether')).toFixed(8) + ' ETH' }&amp;lt;/Label&amp;gt;
                                    {pendingTxItem}
                                &amp;lt;/List.Item&amp;gt;
                                &amp;lt;/List&amp;gt;
                            &amp;lt;/Menu.Item&amp;gt;
                            &amp;lt;Menu.Item&amp;gt;
                                {memberInfo}
                            &amp;lt;/Menu.Item&amp;gt;
                        &amp;lt;/Menu.Menu&amp;gt;
                    );
                } else {
                    accountInfo = (
                        &amp;lt;Menu.Menu position='right'&amp;gt;
                            &amp;lt;Menu.Item&amp;gt;
                                &amp;lt;Button onClick={this.handleImportPrivateKeyClicked} color='blue'&amp;gt;Import private key&amp;lt;/Button&amp;gt;
                            &amp;lt;/Menu.Item&amp;gt;
                        &amp;lt;/Menu.Menu&amp;gt;
                    );
                }
            } else {
                accountInfo = (&amp;lt;Loader inverted active /&amp;gt;);
            }
        }

        return (
            &amp;lt;Menu fixed='top' color='grey' inverted&amp;gt;
                &amp;lt;Head&amp;gt;
                &amp;lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.12/semantic.min.css"&amp;gt;&amp;lt;/link&amp;gt;
                &amp;lt;/Head&amp;gt;
                &amp;lt;Container&amp;gt;
                &amp;lt;Menu.Item&amp;gt;
                    &amp;lt;a href='/'&amp;gt;&amp;lt;Image src='static/images/blockchat.png' height={55} /&amp;gt;&amp;lt;/a&amp;gt;
                &amp;lt;/Menu.Item&amp;gt;
                    {this.account ? accountInfo: (&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;)}
                &amp;lt;/Container&amp;gt;
            &amp;lt;/Menu&amp;gt;
        );
    }
}

export default HeaderMenu;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ContractManager.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import web3 from '../ethereum/web3';
import compiledContract from '../ethereum/build/EtherChat.json';
import TransactionsManager from './TransactionManager';
import appDispatcher from './AppDispatcher';
import Config from '../support/Config';
import Constant from '../support/Constant';
import utils from '../support/Utils';
import crypto from 'crypto';

/**
 * Responsible for interacting with the Ethereum smart contract
 */

export class ContractManager {
    constructor(accountManager, storageManager) {
        this.getContract();
        this.accountManager = accountManager;
        this.storageManager = storageManager;
        this.transactionManager = new TransactionsManager(accountManager);
    }

    // Create a web3 contract object that represent the ethereum smart contract
    getContract = async () =&amp;gt; {
        this.contract = await new web3.eth.Contract(JSON.parse(compiledContract.interface), 
                Config.ENV.ContractAddress);
        appDispatcher.dispatch({
            action: Constant.EVENT.CONTRACT_READY
        })
    }

    // Get current account profile from EtherChat contract's storage
    getProfile = async (address) =&amp;gt; {
        var result = await this.contract.methods.members(this.accountManager.getAddress()).call();
        var profile = {};
        if (result.isMember == 1) {
            profile.isJoined = true;
            profile.avatarUrl = utils.hexStringToAsciiString(result.avatarUrl);
            profile.name = utils.hexStringToAsciiString(result.name);

            this.storageManager.setJoinedStatus(true);
            this.storageManager.setName(this.name);
            this.storageManager.setAvatarUrl(this.avatarUrl);

            appDispatcher.dispatch({
                action: Constant.EVENT.ACCOUNT_INFO_UPDATED,
                profile: profile
            })
        }
        return profile;
    }

    getMemberInfo = async (address, relationship) =&amp;gt; {
        var memberInfo = await this.contract.methods.members(address).call();
        if (memberInfo.isMember) {
            var publicKey = '04' + memberInfo.publicKeyLeft.substr(2) + memberInfo.publicKeyRight.substr(2);
            var name = utils.hexStringToAsciiString(memberInfo.name);
            var avatarUrl = utils.hexStringToAsciiString(memberInfo.avatarUrl);
            this.storageManager.updateContact(address, publicKey, name, avatarUrl, relationship);
        }
    }

    getPastEvents = async (eventName, filters) =&amp;gt; {
        return await this.contract.getPastEvents(eventName, filters);
    }

    joinContract = async(publicKeyBuffer, callback) =&amp;gt; {
        var publicKeyLeft = '0x' + publicKeyBuffer.toString('hex', 0, 32);
        var publicKeyRight = '0x' + publicKeyBuffer.toString('hex', 32, 64);

        this.transactionManager.executeMethod(this.contract.methods.join(publicKeyLeft, publicKeyRight))
            .on(Constant.EVENT.ON_APPROVED, (txHash) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_APPROVED);
            })
            .on(Constant.EVENT.ON_REJECTED, (txHash) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_REJECTED);
            })
            .on(Constant.EVENT.ON_RECEIPT, (receipt) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_RECEIPT);
            })
            .on(Constant.EVENT.ON_ERROR, (error, txHash) =&amp;gt; {
                appDispatcher.dispatch({
                    action: Constant.EVENT.ENCOUNTERED_ERROR,
                    message: error.message,
                    title: "Error"
                });
                if (callback) callback(Constant.EVENT.ON_ERROR);
            });
    }
    // joinContract = async (publicKeyBuffer, callback) =&amp;gt; {

    addContact = async (address, callback) =&amp;gt; {
        console.log(address);

        var method = this.contract.methods.addContact(address);
        this.transactionManager.executeMethod(method)
            .on(Constant.EVENT.ON_APPROVED, (txHash) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_APPROVED);
            })
            .on(Constant.EVENT.ON_RECEIPT, (receipt) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_RECEIPT);
            })
            .on(Constant.EVENT.ON_ERROR, (error, txHash) =&amp;gt; {
                appDispatcher.dispatch({
                    action: Constant.EVENT.ENCOUNTERED_ERROR,
                    message: error.message,
                    title: "Error"
                });
                if (callback) callback(Constant.EVENT.ON_ERROR);
            });
    }

    acceptContactRequest = async (address, callback) =&amp;gt; {
        var method = this.contract.methods.acceptContactRequest(address);
        this.transactionManager.executeMethod(method)
            .on(Constant.EVENT.ON_APPROVED, (txHash) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_APPROVED);
            })
            .on(Constant.EVENT.ON_RECEIPT, (receipt) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_RECEIPT);
            })
            .on(Constant.EVENT.ON_ERROR, (error, txHash) =&amp;gt; {
                appDispatcher.dispatch({
                    action: Constant.EVENT.ENCOUNTERED_ERROR,
                    message: error.message,
                    title: "Error"
                });
                if (callback) callback(Constant.EVENT.ON_ERROR);
            });
    }

    updateProfile = async (name, avatarUrl, callback) =&amp;gt; {
        var nameHex = '0x' + Buffer.from(name, 'ascii').toString('hex');
        var avatarUrlHex = '0x' + Buffer.from(avatarUrl, 'ascii').toString('hex');
        var method = this.contract.methods.updateProfile(nameHex, avatarUrlHex);
        this.transactionManager.executeMethod(method)
            .on(Constant.EVENT.ON_APPROVED, (txHash) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_APPROVED);
            })
            .on(Constant.EVENT.ON_RECEIPT, (receipt) =&amp;gt; {
                if (callback) callback(Constant.EVENT.ON_RECEIPT);
            })
            .on(Constant.EVENT.ON_ERROR, (error, txHash) =&amp;gt; {
                appDispatcher.dispatch({
                    action: Constant.EVENT.ENCOUNTERED_ERROR,
                    message: error.message,
                    title: "Error"
                });
                if (callback) callback(Constant.EVENT.ON_ERROR);
            });
    }

    // A message will be encrypted locally before sending to the smart contract
    sendMessage = async (toAddress, publicKey, message) =&amp;gt; {
        var publicKeyBuffer = Buffer.from(publicKey, 'hex');
        var encryptedRaw = utils.encrypt(message, this.accountManager.computeSecret(publicKeyBuffer));
        var encryptedMessage = '0x' + encryptedRaw.toString('hex');
        var method = this.contract.methods.sendMessage(toAddress, encryptedMessage, utils.getEncryptAlgorithmInHex());

        this.transactionManager.executeMethod(method)
            .on(Constant.EVENT.ON_APPROVED, (txHash) =&amp;gt; {
                this.storageManager.addMyLocalMessage(encryptedMessage, toAddress, utils.getEncryptAlgorithm(), txHash);
                appDispatcher.dispatch({
                    action: Constant.EVENT.MESSAGES_UPDATED,
                    data: toAddress
                });
            })
            .on(Constant.EVENT.ON_REJECTED, (data) =&amp;gt; {
                // do nothing
            })
            .on(Constant.EVENT.ON_RECEIPT, (receipt, ) =&amp;gt; {
                this.storageManager.updateLocalMessage(toAddress, receipt.transactionHash, Constant.SENT_STATUS.SUCCESS);
                appDispatcher.dispatch({
                    action: Constant.EVENT.MESSAGES_UPDATED,
                    data: toAddress
                });
            })
            .on(Constant.EVENT.ON_ERROR, (error, txHash) =&amp;gt; {
                this.storageManager.updateLocalMessage(toAddress, txHash, Constant.SENT_STATUS.FAILED);
                appDispatcher.dispatch({
                    action: Constant.EVENT.MESSAGES_UPDATED,
                    data: toAddress
                });
            });
    }
}

export default ContractManager;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, I'm trying to call the function 'joinContract' {the function of ContractManager class} in HeaderMenu.js using the function handleJoinClicked(). And,boom... code is getting crash after clicking the join button. It's showing the error. This[coontractManager.joinContract] is not a function. Please help.&lt;br&gt;
Please help.&lt;/p&gt;

</description>
      <category>react</category>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
