Error with using create method with HTTPS Post request [ReactJs]

Z

zadders

Guest
so I have recently been working on an admin control panel for a page that displays a list of cards (Some video and some text-based). I am hosting a local API that generates 7 different unique posts of data (these include the post's id, title, url, thumbnailUrl). I have managed to create 2 seperate methods, one of being a delete card and the other being an edit card button. I am now trying to add a "Create" button that opens up a modal popup with empty fields that allows for the admin user to insert it, and once create is clicked, a new data field is added to the API's database.

The code below is for the HelpList.tsx (This is responsible for displaying the list of cards) module created which contains the deleteProduct, editProduct and createProduct methods. I have tried to base my createProduct function on the editProduct one, although I'm unsure if the function will know how to give the card / post an incremented and appropriate Id.

import React, { Component } from "react";
import HelpCard from "./HelpCard";
import "../help/HelpCard.css";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
import Popup from "reactjs-popup";

interface State {
url: string;
title: string;
adminhelpcard: SingleAdminHelpCard[];
error: null;
response: {};
thumbnail: string;
}

interface SingleAdminHelpCard {
id: string;
url: string;
title: string;
thumbnail: string;
}

interface Props {
//createProduct: (title: string, url: string, thumbnail: string) => void;
}

export default class HelpList extends Component<Props, State> {
state = {
title: "",
thumbnail: "",
id: "",
url: "http://localhost:3000/videos/",
adminhelpcard: [],
itemsCountPerPage: 1,
activePage: 1,
error: null,
response: {}
//isEditProduct: true,
//isAddProduct: true
};

loadAdminHelpCard = () => {
axios
.get(this.state.url)
.then((res) => {
this.setState((prevState) => {
const adminhelpcard = prevState.adminhelpcard;
return {
adminhelpcard: [...prevState.adminhelpcard, ...res.data],
url: res.data.next
};
});
})
.catch(function(error) {
// handle error
console.log(error);
});
};
static props: any;

async componentDidMount() {
const apiUrl = "http://localhost:3000/videos/";
const res = await axios.get(this.state.url);
this.setState({ adminhelpcard: res.data });
fetch(apiUrl)
.then((res) => res.json())
.then(
(result) => {
this.setState({
adminhelpcard: result
});
},
(error) => {
this.setState({ error });
}
);
}

deleteProduct(id: any) {
const { adminhelpcard } = this.state;

const apiUrl = `http://localhost:3000/videos/${id}`;

const options = {
method: "DELETE"
};

fetch(apiUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);

console.log(this.state.id);
}

editProduct(id: any, title: string, url: string, thumbnail: string) {
const { adminhelpcard } = this.state;
const apiUrl = `http://localhost:3000/videos/${id}`;

const options = {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title,
url,
thumbnail
})
};

fetch(apiUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);
}

createProduct(title: string, url: string, thumbnail: string) {
const apiUrl = `http://localhost:3000/videos/`;

const options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title,
url,
thumbnail
})
};

fetch(apiUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result
});
},
(error) => {
this.setState({ error });
}
);
}

render() {
console.log(this.state.adminhelpcard);
return (
<div>
<React.Fragment>
{this.state.adminhelpcard ? (
<div className="row">
<InfiniteScroll
pageStart={1}
loadMore={this.loadAdminHelpCard}
hasMore={this.state.url ? true : false}
threshold={0}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}>
{this.state.adminhelpcard.map((adminhelpcard: SingleAdminHelpCard, i) => (
<HelpCard
id={adminhelpcard.id}
key={adminhelpcard.id + i}
title={adminhelpcard.title}
url={adminhelpcard.url}
thumbnail={adminhelpcard.thumbnail}
deleteProduct={this.deleteProduct.bind(this)}
editProduct={this.editProduct.bind(this)}
/>
))}
</InfiniteScroll>
</div>
) : (
<h1>Loading Cards</h1>
)}
</React.Fragment>
</div>
);
}
}


I am then calling the editProduct and deleteProduct functions within buttons that are available in the HelpCard.tsx which is responsible for generating the structure of the card itself.

The code below is for the videoCard which also contains the component (modal tooltip) that contains the editProduct fields and functions:

<div className="horizontalCard">
<div className="innerCard">
<div className="leftImage">
<img
className="Sprite"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ tooManyRequests: true })}
src={this.state.thumbnail}
style={
this.state.tooManyRequests
? { display: "none" }
: this.state.imageLoading
? { display: "null" }
: { display: "null" }
}
/>
</div>
<div className="rightText">
<div className="card-body">
{this.state.title}
<div className="cardButtons">
<Popup trigger={<button className="btn">Edit</button>} position="left center">
<form
onSubmit={(e) => e.preventDefault()}
id="videoCardEdit"
style={{ width: "auto", height: "auto" }}>
<div>
<div>
<label>Title:</label>
<input
name="videoCardTitle"
onChange={(e) => {
this.setState({ title: e.target.value });
}}
value={this.state.title}></input>
</div>
<div>
<label>URL:</label>
<input
name="videoCardURL"
onChange={(e) => {
this.setState({ url: e.target.value });
}}
value={this.state.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
name="videoCardThumbnail"
onChange={(e) => {
this.setState({ thumbnail: e.target.value });
}}
value={this.state.thumbnail}></input>
</div>
</div>
<button
className="btnConfirm"
style={{
float: "left"
}}
onClick={() =>
this.props.editProduct(
this.props.id,
this.state.title,
this.state.url,
this.state.thumbnail
)
}
id="confirmModalBtn">
confirm
</button>
</form>
</Popup>
<button onClick={() => this.props.deleteProduct(this.props.id)} className="btn">
Delete
</button>
</div>
</div>
</div>
</div>
</div>


Finally, I am then inserting the "Create" button within my HelpAdmin.view.tsx page (This is more or less my index.tsx / app.tsx for this task, since I am displaying my list and button within this panel page). I am trying to implement the Create button so that it is displayed on top of the component that is created. The code for the following page is as follows:

import React, { Component } from "react";
import HelpList from "../components/helpAdmin/help/HelpList";
import "../components/helpAdmin/help/HelpList";

import Popup from "reactjs-popup";


interface Props {
createProduct: (title: string, url: string, thumbnail: string) => void;
}

interface State {
title: string;
thumbnail: string;
id: string;
url: string;
}

export class HelpAdminView extends Component<Props, State> {
componentDidMount() {}

render() {
return (
<main>
<div className="box">
<Popup trigger={<button className="btn"> Create a new card</button>} position="right center">
<div>
<div>
<label>Title:</label>
<input
name="createCardTitle"
onChange={(e) => {
this.setState({ title: e.target.value });
}}
value={this.state.title}></input>
</div>
<div>
<label>URL:</label>
<input
name="createCardURL"
onChange={(e) => {
this.setState({ url: e.target.value });
}}
value={this.state.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
name="createCardThumbnail"
onChange={(e) => {
this.setState({ thumbnail: e.target.value });
}}
value={this.state.thumbnail}></input>
</div>

<button
style={{
float: "left"
}}
onClick={() => this.props.createProduct(this.state.title, this.state.url, this.state.thumbnail)}
className="btnCreate"
id="confirmModalBtn">
Create
</button>
</div>
</Popup>
<HelpList />
</div>
</main>
);
}
}
export default HelpAdminView;


This code seems to constantly throw me the following error when trying to run the project and it is as follows:

Type error: Property 'createProduct' is missing in type '{}' but required in type 'Readonly<Props>'. TS2741


I am unsure as to why this error is being thrown even though I've tried to call this function the same way I've tried to call the previously working ones. IS there something I am clearly missing over here?

Thank you for any help in advance!

Continue reading...
 
Top