What is the best way to fetch the title property from my Campaign Contract for displaying it in the render method?

I'm currently working on a unique crowdfunding DApp that requires constant access to contract variables through function calls for retrieval purposes.

The getDeployedCampaigns function is responsible for returning an array of deployed campaign addresses. These addresses are then passed down to a map function in order to generate a react component with the corresponding address displayed on it.

In an ideal situation, I would also like to retrieve and utilize the campaignTitle variable within the campaign contract. However, I am facing difficulties finding a way to do this without disrupting the entire rendering process.

This is the current functioning code:

import { Card, Button } from "semantic-ui-react";
import factory from "../ethereum/factory";
import Layout from "../components/Layout";
import { Link } from "../routes";

class CampaignIndex extends Component {
  static async getInitialProps() {
    const campaigns = await factory.methods.getDeployedCampaigns().call();

    return { campaigns };
  }
  renderCampaigns() {
    const items = this.props.campaigns.map((address) => {
      return {
        header: address,
        description: (
          <Link route={`/campaigns/${address}`}>
            <a>View Campaign</a>
          </Link>
        ),
        fluid: true,
      };
    });
    return <Card.Group items={items} />;
  }
  render() {
    return (
      <Layout>
        <div>
          <h3>Open Campaigns</h3>
          <Link route="/campaigns/new">
            <a>
              <Button
                floated="right"
                content="Create Campaign"
                icon="add circle"
                primary
              />
            </a>
          </Link>
          {this.renderCampaigns()}
        </div>
      </Layout>
    );
  }
}

export default CampaignIndex;

And here is what I am attempting to accomplish, although it's not yet functional:

import { Card, Button } from 'semantic-ui-react';
import factory from '../ethereum/factory';
import Layout from '../components/Layout';
import { Link } from '../routes';
import Campaign from '../ethereum/campaign';

class CampaignIndex extends Component {
  static async getInitialProps() {
    const campaigns = await factory.methods.getDeployedCampaigns().call();

    const campaignInfo = Promise.all(
      campaigns.map(async (address) => {
        const campaign = Campaign(address);
        const title = await campaign.methods.campaignTitle().call();

        return {
          header: title,
          meta: address,
          description: (
            <Link route={`/campaigns/${address}`}>
              <a>View Campaign</a>
            </Link>
          ),
          fluid: true,
        };
      })
    );

    return { campaignInfo };
  }
  renderCampaigns() {
    const items = this.props.campaignInfo;
    return <Card.Group items={items} />;
  }
  render() {
    return (
      <Layout>
        <div>
          <h3>Open Campaigns</h3>
          <Link route="/campaigns/new">
            <a>
              <Button
                floated="right"
                content="Create Campaign"
                icon="add circle"
                primary
              />
            </a>
          </Link>
          {this.renderCampaigns()}
        </div>
      </Layout>
    );
  }
}

export default CampaignIndex;

Furthermore, attached is the Smart Contract for your perusal:


contract CampaignFactory {
    address[] public deployedCampaigns;

    function createCampaign(uint minimum, string title, string description) public {
        address newCampaign = new Campaign(minimum, msg.sender, title, description);
        deployedCampaigns.push(newCampaign);
    }

    function getDeployedCampaigns() public view returns (address[]) {
        return deployedCampaigns;
    }
}

contract Campaign {
    struct Request {
        string description;
        uint value;
        address recipient;
        bool complete;
        uint approvalCount;
        mapping(address => bool) approvals;
    }

    Request[] public requests;
    address public manager;
    uint public minimumContribution;
    string public campaignTitle;
    string public campaignDescription;
    mapping(address => bool) public approvers;
    uint public approversCount;

    modifier restricted() {
        require(msg.sender == manager);
        _;
    }

    function Campaign(uint minimum, address creator, string givenTitle, string givenDescription) public {
        manager = creator;
        minimumContribution = minimum;
        campaignTitle = givenTitle;
        campaignDescription = givenDescription;

        
    }

    function contribute() public payable {
        require(msg.value > minimumContribution);

        approvers[msg.sender] = true;
        approversCount++;
    }

    function createRequest(string description, uint value, address recipient) public restricted {
        Request memory newRequest = Request({
           description: description,
           value: value,
           recipient: recipient,
           complete: false,
           approvalCount: 0
        });

        requests.push(newRequest);
    }

    function approveRequest(uint index) public {
        Request storage request = requests[index];

        require(approvers[msg.sender]);
        require(!request.approvals[msg.sender]);

        request.approvals[msg.sender] = true;
        request.approvalCount++;
    }

    function finalizeRequest(uint index) public restricted {
        Request storage request = requests[index];

        require(request.approvalCount > (approversCount / 2));
        require(!request.complete);

        request.recipient.transfer(request.value);
        request.complete = true;
    }
    
    function getSummary() public view returns (
      uint, uint, uint, uint, address
      ) {
        return (
          minimumContribution,
          this.balance,
          requests.length,
          approversCount,
          manager
        );
    }
    
    function getRequestsCount() public view returns (uint) {
        return requests.length;
    }
}

Answer №1

When dealing with the factory contract, you are directly returning an array of items, indicating that you are utilizing a more recent version of solidity. However, in the Campaign contract, you are still using function Campaign, which was originally intended for use as a constructor in earlier versions of solidity. Since you are working with a newer version of solidity, it is recommended to initialize the contract using the constructor keyword. By not utilizing the constructor keyword, you are neglecting to assign a value to the title.

It is advisable to replace function Campaign with constructor

constructor(uint minimum, address creator, string givenTitle, string givenDescription) {
        manager = creator;
        minimumContribution = minimum;
        campaignTitle = givenTitle;
        campaignDescription = givenDescription;
        
    }

Answer №2

Perhaps the reason for this issue is that the CampaignName was not fetched in the getSummary function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I have a parent DIV with a child DIV, and I am looking to use jQuery to select the last child DIV. The parent DIV has an

In my HTML code, I have a parent div called "allcomments_4" which contains several child divs with unique IDs (oneEntry), each with their own children. My goal is to locate and retrieve the content inside the last child of the parent node (lastComment) and ...

Subtracted TypeScript concept

Is it possible to create a modified type in Typescript for React components? import {Component, ComponentType} from 'react'; export function connect<S, A>(state: () => S, actions: A){ return function createConnected<P>(componen ...

Using react-hook-form to easily update form data

While working on my project with react-hook-form for updating and creating details, I encountered a problem specifically in the update form. The values were not updating properly as expected. The issue seems to be within the file countryupdate.tsx. import ...

Creating a Piechart in Kendo UI that is bound to hierarchal remote data

I am facing an issue with binding remote data to a pie chart while managing a grid with dropdown sorting options. The grid is working fine, but I am unable to display the hierarchical data on the pie chart as categories. <!DOCTYPE html> <html> ...

Personalized Shade Selection for Papyrus

Is there a method to specifically alter the color of the box-shadow for the mui Paper component? I have a black background, making the shadow not visible. I've tried createMuiTheme({ overrides: { MuiPaper: { root: { boxShadow: & ...

Having issues with the media query for the SearchIcon in Material-UI and React - not functioning as

I've been struggling to get the media query for the searchIcon in const search to function properly. The other media queries seem to be working fine, but this one is giving me trouble. I attempted to apply it to const styles instead of const search, ...

What could be the reason why the initial console.log is failing to print?

Apologies for the oversight. The !== was a mistake that slipped past me before posting. Thank you for your understanding. I am a beginner in Javascript. I have written this function with winston: function setlogger(log_level = "warn", logfile, scree ...

Tab knockout binding

I have a section in my HTML with 2 tabs. The default tab is working properly, but when I attempt to switch to the other tab, I encounter an error. Can anyone provide assistance in determining why this error occurs? Here is the HTML code: <ul class="na ...

Title: How to Build a Dynamic Logo Carousel with React and CSS without External Dependencies

Currently, I am in the process of integrating a logo carousel into my React web application using CSS. My goal is to create a slider that loops infinitely, with the last logo seamlessly transitioning to the first logo and continuing this cycle indefinitely ...

Error message: The CustomEvent is not properly defined in the NextJS project, causing a Reference

I encountered an error: ReferenceError: CustomEvent is not defined. I am aware that CustomEvent is only available on the client side (browser), but I am attempting to utilize this function as an event: const mouseEnterHandler = () => { eventDispatc ...

In the React guessing game, the correct answer does not trigger a message to display

Currently I am delving into the world of react and took a shot at coding the guess the number game. Utilizing several tutorials, here is the result of my efforts: const {useState} = React; function App() { const [ans, setAns] = useState(Math.round(Ma ...

Is it possible to reset the text within the text box when the form is being submitted using the load() ajax function?

I am working on implementing a comment feature where the data entered in the form is appended and displayed after submission. Here is my HTML form: <table> <tr><td>Name :</td><td> <input type="text" id="name"/></td&g ...

Learn the process of adjusting opacity for a specific color in CSS

At the moment, this is the code I'm using to apply a color to an element using jss. const styleSheet = theme => ({ root: { backgroundColor: theme.colors.red, }, }) I am interested in finding out if there is a way to add opacity based o ...

Search a database for a specific set of ObjectID using Mongoose

I'm currently developing an API using node.js, express, and mongoose. As I am still new to mongosse, I have been exploring different approaches to achieve what I need. In my database, I have two collections: users and expenses. Here's an exampl ...

Enhance your loader functionality by dynamically updating ng-repeat using ng-if

To better illustrate my issue, here is a link to the fiddle I created: https://jsfiddle.net/860Ltbva/5/ The goal is to show a loading message while the ng-repeat loop is still loading and hide it once all elements have been loaded. I referenced this help ...

The server appears to be active, but there is a lack of content rendering when using React, Node

When I attempt to run the code in app.jsx, nothing displays even though the index.html is functioning properly. Code from Server.js: var express = require('express'); server.js page var app = express(); app.use(express.static('public' ...

JavaScript basic calculator app failed to generate an error as anticipated

For my homework assignment, I am developing a basic calculator application using JavaScript. My main task is to ensure that the input numbers are limited to only two and that they are valid numbers; otherwise, an error should be thrown. Initially, concern ...

The performance of the animation on http://responsive-nav.com/ becomes erratic when viewed on Android devices

Recently, I came across a fantastic plugin that works perfectly on regular computer browsers. However, when I tested it on my android phone, the css3 animation for the dropdown appeared choppy and seemed to be dropping frames. Does anyone have suggestions ...

Steps for transforming an Array of hierarchical data into the correct JSON format for D3 Tree Region visualization

I am struggling with converting an array of hierarchy data into the correct Object format. Here is what I am trying to convert: [ {"PARENT_ID": 0,"CHILD_ID": 1,"NAME": "Quality","LEVEL_A": 0}, {&qu ...

Issue with child rows not functioning properly in DataTables when utilizing Datetime-moment

I've successfully integrated this data into live.datatables.net and almost have it running smoothly. However, I am encountering an issue with displaying the last detail as a child element. The final part of the row should be shown with the label "Mes ...