upload image and text with form - javascript

I'm learning React with Strapi.
I made a form to add data to the database. I manage to send my img in the upload api and the text data in the Animals api, however, I can't manage to link the two. Ie to make sure that the image also goes on the animal that I add.
Thank you all for your future help.
import React from "react";
import { useForm } from "react-hook-form";
import axios from "axios";
import React from "react";
import { useForm } from "react-hook-form";
import axios from "axios";
class AddAnimal extends React.Component {
constructor(props) {
super(props);
this.state = {
modifiedData: {
nom: '',
description: '',
image : '',
races: [],
images :[],
},
allRaces: [],
error: null,
};
}
onImageChange = event => {
console.log(event.target.files);
this.setState({
images: event.target.files,
});
};
componentDidMount = async () => {
try {
const response = await axios.get('http://localhost:1337/api/races');
this.setState({ allRaces: response.data.data });
} catch (error) {
this.setState({ error });
}
};
handleInputChange = ({ target: { name, value } }) => {
this.setState(prev => ({
...prev,
modifiedData: {
...prev.modifiedData,
[name]: value,
},
}));
};
handleSubmit = async e => {
e.preventDefault();
const formData = new FormData();
Array.from(this.state.images).forEach(image => {
formData.append('files', image);
});
try {
const response = await axios.post('http://localhost:1337/api/animaux?populate=*',
{
"data": {
nom: this.state.modifiedData.nom,
Description: this.state.modifiedData.description,
image : this.images,
races: this.state.modifiedData.races
}
})
axios
.post(`http://localhost:1337/api/upload`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
console.log(response);
} catch (error) {
this.setState({ error });
}
};
renderCheckbox = race => {
const {
modifiedData: { races },
} = this.state;
const isChecked = races.includes(race.id);
const handleChange = () => {
if (!races.includes(race.id)) {
this.handleInputChange({
target: { name: 'races', value: races.concat(race.id) },
});
} else {
this.handleInputChange({
target: {
name: 'races',
value: races.filter(v => v !== race.id),
},
});
}
};
return (
<div key={race.id}>
<label htmlFor={race.id}>{race.attributes.nom}</label>
<input
type="checkbox"
checked={isChecked}
onChange={handleChange}
name="races"
id={race.id}
/>
</div>
);
};
render() {
const { error, allRaces, modifiedData } = this.state;
if (error) {
return <div>An error occured: {error.message}</div>;
}
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<h3>Ajouter un animal</h3>
<br />
<label>
Name:
<input
type="text"
name="nom"
onChange={this.handleInputChange}
value={modifiedData.name}
/>
</label>
<label>
Description:
<input
type="text"
name="description"
onChange={this.handleInputChange}
value={modifiedData.description}
/>
</label>
<input type="file" name="images" value={this.images} onChange={this.onImageChange}/>
<div>
<br />
<b>Select races</b>
{allRaces.map(this.renderCheckbox)}
</div>
<br />
<button type="submit">Ajouter</button>
</form>
</div>
);
}
}
export default AddAnimal;

Related

Sending multipart Form in ReactJS vs Postman

I've created a registration api that works fine using postman, I added some values there plus image an everything stores correctly, data an image, Later I started my React form and only text works, image is not currently sent to the api I guess.
Doing console.log() api in Node:
console.log(req.files);
with React Form: []
with Postman: an array of object that perfectly works
req.files output using postman
{
fieldname: 'images',
originalname: 'Screen Shot 2021-02-22 at 17.18.41.png',
encoding: '7bit',
mimetype: 'image/png',
destination: 'uploads/',
filename: '091f77f82fb805b1ede9f23205cc578e',
path: 'uploads/091f77f82fb805b1ede9f23205cc578e',
size: 37052
}
Here's my react classes:
httpService.js
import axios from "axios";
import { toast } from "react-toastify";
axios.interceptors.response.use(null, (error) => {
const expectedError =
error.response &&
error.response.status >= 400 &&
error.response.status < 500;
if (!expectedError) {
console.log("Loggind the error: ", error);
toast("An unexpected error ocurred.");
}
return Promise.reject(error);
});
export default {
post: axios.post
};
itemService.js
export function saveItem(item) {
const headers = {
'Content-Type': 'multipart/form-data',
};
return http.post(MY_ENDPOINT, item, headers);
}
itemForm.js
import React from "react";
import Joi from "joi-browser";
import Form from "./common/form";
import { saveItem } from "../services/itemService";
class ItemForm extends Form {
state = {
data: { title: "", description: "", category: "", images: "" },
categories: [],
errors: {},
};
schema = {
_id: Joi.string(),
title: Joi.string().required().label("Title"),
description: Joi.string().required().label("Description"),
category: Joi.string().required().label("Category"),
images: Joi.required().label("Image"),
};
doSubmit = async () => {
console.log('form data> ', this.state.data); // This shows the correct object.
let formData = new FormData();
formData.append('title', this.state.data.title);
formData.append('description', this.state.data.description);
formData.append('category', this.state.data.category);
formData.append('images', this.state.data.images);
try {
await saveItem(formData);
} catch (ex) {
}
};
render() {
return (
<div>
<h1>New item</h1>
<form onSubmit={this.handleSubmit}>
{this.renderInput("title", "Title")}
{this.renderInput("description", "Description")}
{this.renderSelect(
"category",
"title",
"Category",
this.state.categories
)}
{this.renderInputFile("images", "images", "file", false)}
{this.renderButton("Register")}
</form>
</div>
);
}
}
export default ItemForm;
form.jsx (The extended class)
import React, { Component } from "react";
import Joi from "joi-browser";
import Input from "./input";
import Select from "./select";
class Form extends Component {
state = {
data: {},
errors: {},
};
validate = () => {
const options = { abortEarly: false };
const { error } = Joi.validate(this.state.data, this.schema, options);
if (!error) return null;
const errors = {};
for (let item of error.details) errors[item.path[0]] = item.message;
return errors;
};
validateProperty = ({ name, value }) => {
const obj = { [name]: value };
const schema = { [name]: this.schema[name] };
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;
};
handleSubmit = (e) => {
e.preventDefault();
const errors = this.validate();
this.setState({ errors: errors || {} });
if (errors) return;
this.doSubmit();
};
handleChange = ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(input);
if (errorMessage) errors[input.name] = errorMessage;
else delete errors[input.name];
const data = { ...this.state.data };
data[input.name] = input.value;
this.setState({ data, errors });
};
handleInputFileChange = ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(input);
if (errorMessage) errors[input.name] = errorMessage;
else delete errors[input.name];
const data = { ...this.state.data };
data[input.name] = input.value;
this.setState({ data, errors });
};
renderButton(label) {
return (
<button className="btn btn-primary" disabled={this.validate()}>
{label}
</button>
);
}
renderInput(name, label, type = "text", multiple = false) {
const { data, errors } = this.state;
return (
<Input
type={type}
name={name}
value={data[name]}
label={label}
onChange={this.handleChange}
error={errors[name]}
multiple={multiple}
/>
);
}
renderSelect(name, contentField, label, options) {
const { data, errors } = this.state;
return (
<Select
name={name}
value={data[name]}
label={label}
contentField={contentField}
options={options}
onChange={this.handleChange}
error={errors[name]}
/>
);
}
renderInputFile(name, label, type = "text", multiple = false) {
const { data, errors } = this.state;
return (
<Input
type={type}
name={name}
value={data[name]}
label={label}
onChange={this.handleInputFileChange}
error={errors[name]}
multiple={multiple}
accept="image/*"
/>
);
}
}
export default Form;

Cannot read property 'data' of undefined in ReactJs and SwaggerUI

I am working with ReactJs and Fetch API from Swagger UI. I code for Room management, this is my code for that
In actions.js file
// Room type action
export const actFetchRoomTypesRequest = () => {
return (dispatch) => {
return callApi('admin/host-room-types', 'GET', null).then((res) => {
dispatch(actFetchRoomTypes(res.data));
});
};
};
export const actFetchRoomTypes = (roomTypes) => {
return {
type: Types.FETCH_ROOMTYPES,
roomTypes,
};
};
export const actDeleteRoomTypeRequest = (id) => {
return (dispatch) => {
return callApi(`admin/host-room-types/${id}`, 'DELETE', null).then((res) => {
dispatch(actFetchRoomTypesRequest());
});
};
};
export const actAddRoomTypeRequest = (roomType) => {
return (dispatch) => {
return callApi(`admin/host-room-types`, 'POST', roomType).then((res) => {
return callApi(`admin/host-room-types`).then((ress) => {
dispatch(actFetchRoomTypes(ress.data));
});
});
};
};
export const actAddRoomType = (roomType) => {
return {
type: Types.ADD_ROOMTYPE,
roomType,
};
};
export const actGetRoomTypeRequest = (id) => {
return (dispatch) => {
return callApi(`admin/host-room-types/${id}`, 'GET', null).then((res) => {
dispatch(actGetRoomType(res.data));
});
};
};
export const actGetRoomType = (roomType) => {
return {
type: Types.EDIT_ROOMTYPE,
roomType,
};
};
export const actUpdateRoomTypeRequest = (roomType) => {
return (dispatch) => {
return callApi(`admin/host-room-types/${roomType.id}`, 'PUT', roomType).then((res) => {
return callApi(`admin/host-room-types`).then((ress) => {
dispatch(actFetchRoomTypes(ress.data));
});
});
};
};
export const actUpdateRoomType = (roomType) => {
return {
type: Types.UPDATE_ROOMTYPE,
roomType,
};
};
In RoomTypeItem.js which the place I show all action for that
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class RoomTypeItem extends Component {
constructor(props) {
super(props);
console.log('constructor');
}
onDelete = (id) => {
console.log(id);
if (window.confirm('ban muon xoa?')) {
this.props.onDelete(id);
}
};
onSelectRoomType = (id) => {
console.log('onSelect' + id);
this.props.onSelect(id);
};
render() {
var { roomType, index } = this.props;
console.log('render' + roomType.id + this.props.checked);
return (
<tr>
<td>
<input
type="checkbox"
className="delid[]"
checked={this.props.checked}
onChange={() => this.onSelectRoomType(roomType.id)}
/>
</td>
<td>{index + 1}</td>
<td>{roomType.name}</td>
<td>{roomType.description}</td>
<td>
<Link to={`/roomType/${roomType.id}/edit`} className="btn btn-warning mr-10">
Update
</Link>
</td>
</tr>
);
}
}
export default RoomTypeItem;
And in RoomTypeActionPage have code like this
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { actAddRoomTypeRequest, actGetRoomTypeRequest, actUpdateRoomTypeRequest } from './../../actions/index';
import { connect } from 'react-redux';
class RoomTypeActionPage extends Component {
constructor(props) {
super(props);
this.state = {
id: '',
txtName: '',
txtDescription: '',
};
}
componentDidMount() {
var { match } = this.props;
if (match) {
var id = match.params.id;
this.props.onEditRoomType(id);
}
}
componentWillReceiveProps(nextProps) {
if (nextProps && nextProps.itemEditing) {
var { itemEditing } = nextProps;
this.setState({
id: itemEditing.id,
txtName: itemEditing.name,
txtDescription: itemEditing.description,
});
}
}
onChange = (e) => {
var target = e.target;
var name = target.name;
var value = target.type === 'checkbox' ? target.checked : target.value;
this.setState({
[name]: value,
});
};
onSave = (e) => {
e.preventDefault();
var { id, txtName, txtDescription } = this.state;
var { history } = this.props;
var roomType = {
id: id,
name: txtName,
description: txtDescription,
};
if (id) {
//update
this.props.onUpdateRoomType(roomType);
} else {
this.props.onAddRoomType(roomType);
}
history.goBack();
};
render() {
var { txtName, txtDescription } = this.state;
return (
<div className="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<form onSubmit={this.onSave}>
<div className="form-group">
<label>Name:</label>
<input
type="text"
className="form-control"
name="txtName"
value={txtName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Description:</label>
<input
type="text"
className="form-control"
name="txtDescription"
value={txtDescription}
onChange={this.onChange}
/>
</div>
<Link to="/roomType-list" className="btn btn-danger mr-10">
Cancel
</Link>
<button type="submit" className="btn btn-primary">
Save
</button>
</form>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
itemEditing: state.itemEditing,
};
};
const mapDispatchToProps = (dispatch, props) => {
return {
onAddRoomType: (roomType) => {
dispatch(actAddRoomTypeRequest(roomType));
},
onEditRoomType: (id) => {
dispatch(actGetRoomTypeRequest(id));
},
onUpdateRoomType: (roomType) => {
dispatch(actUpdateRoomTypeRequest(roomType));
},
};
};
export default connect(mapStateToProps, mapDispatchToProps)(RoomTypeActionPage);
And this is my Reducer
import * as Types from './../constants/ActionTypes';
var initialState = {
loading: false,
data: [],
};
var findIndex = (roomTypes, id) => {
var result = -1;
roomTypes.data.forEach((roomType, index) => {
if (roomType.id === id) {
result = index;
}
});
return result;
};
const roomTypes = (state = initialState, action) => {
var index = -1;
var { id, roomType } = action;
switch (action.type) {
case Types.FETCH_ROOMTYPES:
state = action.roomTypes;
return { ...state };
case Types.DELETE_ROOMTYPE:
index = findIndex(state, id);
state.splice(index, 1);
return { ...state };
case Types.ADD_ROOMTYPE:
state.data.push(action.roomType);
return { ...state };
case Types.UPDATE_ROOMTYPE:
index = findIndex(state, roomType.id);
state[index] = roomType;
return { ...state };
default:
return { ...state };
}
};
export default roomTypes;
I do not know when I run my code it shows me an error like this
I already to check all but I can realize where I code wrong for that. PLease help me, I need you, Thank thank so much
This is my link for swagger UI : here
This is my apiCaller
import axios from 'axios';
import * as Config from './../constants/Config';
export default function callApi(endpoint, method = 'GET', body) {
return axios({
method: method,
url: `${Config.API_URL}/${endpoint}`,
data: body,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization:
'Bearer ' +
'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTU5Njg4MTYxMSwiZXhwIjoxNjEyOTQzNjEwfQ.eXkXWuuIMk94uOtVZQSNysbfJyIQuP5dIFqS06Kx-KsYVCkVEAbU01IhwJpkR4YtgXt8idkN4MM0cT76Xre7Sg',
},
}).catch((err) => {
console.log(err);
});
}

Uncaught TypeError: Cannot convert undefined or null to object React JS

I am trying to get my photo blog/phlog manager component functional. However the console says the there an undefined object through props.
import React, { Component } from 'react';
import axios from 'axios';
import DropzoneComponent from 'react-dropzone-component';
import "../../../node_modules/react-dropzone-component/styles/filepicker.css";
import "../../../node_modules/dropzone/dist/min/dropzone.min.css";
class PhlogEditor extends Component {
constructor(props) {
super(props);
this.state = {
id: '',
phlog_status: '',
phlog_image: '',
editMode: false,
position: '',
apiUrl: 'http://127.0.0.1:8000/phlogapi/phlog/',
apiAction: 'post'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.componentConfig = this.componentConfig.bind(this);
this.djsConfig = this.djsConfig.bind(this);
this.handlePhlogImageDrop = this.handlePhlogImageDrop.bind(this);
this.deleteImage = this.deleteImage.bind(this);
this.phlogImageRef = React.createRef();
}
deleteImage(event) {
event.preventDefault();
axios
.delete(
`http://127.0.0.1:8000/phlogapi/phlog/${this.props.id}/delete`,
{ withCredentials: true }
)
.then(response => {
this.props.handlePhlogImageDelete();
})
.catch(error => {
console.log('deleteImage failed', error)
});
}
The error is occuring at Object.keys(this.props.phlogToEdit).length>0
componentDidUpdate() {
if (Object.keys(this.props.phlogToEdit).length > 0) {
// debugger;
const {
id,
phlog_image,
phlog_status,
position
} = this.props.phlogToEdit;
this.props.clearPhlogsToEdit();
this.setState({
id: id,
phlog_image: phlog_image || '',
phlog_status: phlog_status || '',
position: position || '',
editMode: true,
apiUrl: `http://127.0.0.1:8000/phlogapi/phlog/${this.props.id}/update`,
apiAction: 'patch'
});
}
}
handlePhlogImageDrop() {
return {
addedfile: file => this.setState({ phlog_image_url: file })
};
}
componentConfig() {
return {
iconFiletypes: [".jpg", ".png"],
showFiletypeIcon: true,
postUrl: "https://httpbin.org/post"
};
}
djsConfig() {
return {
addRemoveLinks: true,
maxFiles: 3
};
}
buildForm() {
let formData = new FormData();
formData.append('phlog[phlog_status]', this.state.phlog_status);
if (this.state.phlog_image) {
formData.append(
'phlog[phlog_image]',
this.state.phlog_image
);
}
return formData;
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
axios({
method: this.state.apiAction,
url: this.state.apiUrl,
data: this.buildForm(),
withCredentials: true
})
.then(response => {
if (this.state.phlog_image) {
this.phlogImageRef.current.dropzone.removeAllFiles();
}
this.setState({
phlog_status: '',
phlog_image: ''
});
if (this.props.editMode) {
this.props.handleFormSubmission(response.data);
} else {
this.props.handleSuccessfulFormSubmission(response.data);
}
})
.catch(error => {
console.log('handleSubmit for phlog error', error);
});
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit} className='phlog-editor-wrapper'>
<div className='one-column'>
<div className='image-uploaders'>
{this.props.editMode && this.props.phlog_image_url ? (
<div className='phlog-manager'>
<img src={this.props.phlog.phlog_image_url} />
<div className='remove-image-link'>
<a onClick={() => this.deleteImage('phlog_image')}>
Remove Photos
</a>
</div>
</div>
) : (
<DropzoneComponent
ref={this.phlogImageRef}
config={this.componentConfig()}
djsConfig={this.djsConfig()}
eventHandlers={this.handlePhlogImageDrop()}
>
<div className='phlog-msg'>Phlog Photo</div>
</DropzoneComponent>
)}
</div>
<button className='btn' type='submit'>Save</button>
</div>
</form>
);
}
}
export default PhlogEditor;
I do not understand how the object is empty when the props are coming from the parent component
phlog-manager.js:
import React, { Component } from "react";
import axios from "axios";
import PhlogEditor from '../phlog/phlog-editor';
export default class PhlogManager extends Component {
constructor() {
super();
Here I define phlogToEdit as an object to pass as props to phlogEditor child component
this.state = {
phlogItems: [],
phlogToEdit: {}
};
this.handleNewPhlogSubmission = this.handleNewPhlogSubmission.bind(this);
this.handleEditPhlogSubmission = this.handleEditPhlogSubmission.bind(this);
this.handlePhlogSubmissionError = this.handlePhlogSubmissionError.bind(this);
this.handleDeleteClick = this.handleDeleteClick.bind(this);
this.handleEditClick = this.handleEditClick.bind(this);
this.clearPhlogToEdit = this.clearPhlogToEdit.bind(this);
}
clearPhlogToEdit() {
this.setState({
phlogToEdit: {}
});
}
handleEditClick(phlogItem) {
this.setState({
phlogToEdit: phlogItem
});
}
handleDeleteClick(id) {
axios
.delete(
`http://127.0.0.1:8000/phlogapi/phlog/${id}`,
{ withCredentials: true }
)
.then(response => {
this.setState({
phlogItems: this.state.phlogItems.filter(item => {
return item.id !== id;
})
});
return response.data;
})
.catch(error => {
console.log('handleDeleteClick error', error);
});
}
handleEditPhlogSubmission() {
this.getPhlogItems();
}
handleNewPhlogSubmission(phlogItem) {
this.setState({
phlogItems: [phlogItem].concat(this.state.phlogItems)
});
}
handlePhlogSubmissionError(error) {
console.log('handlePhlogSubmissionError', error);
}
getPhlogItems() {
axios
.get('http://127.0.0.1:8000/phlogapi/phlog',
{
withCredentials: true
}
)
.then(response => {
this.setState({
phlogItems: [...response.data]
});
})
.catch(error => {
console.log('getPhlogItems error', error);
});
}
componentDidMount() {
this.getPhlogItems();
}
render() {
return (
<div className='phlog-manager'>
<div className='centered-column'>
This is where the object, phlogToEdit is being passed as props to child component mentioned
<PhlogEditor
handleNewPhlogSubmission={this.handleNewPhlogSubmission}
handleEditPhlogSubmission={this.handleEditPhlogSubmission}
handlePhlogSubmissionError={this.handleEditPhlogSubmission}
clearPhlogToEdit={this.clearPhlogToEdit}
phlogToEdit={this.phlogToEdit}
/>
</div>
</div>
);
}
}
#Jaycee444 solved the problem it was the parent component!
phlogToEdit={this.state.phlogToEdit}

Set input value automatically on a fetch request

I present my problem to you
In the following code, I'm trying to retrieve phone numbers from an API and then show them in a Card; in each card, I have a different number which is displayed
and also in each card, I have an input field to enter the phone number which I obtained before.
My problem is that I don't want to fill in the input manually with the recovered number.
So basically I would like to start my function without having to fill in this field manually.
Do you have any idea how to do this?
I tried to simplify the code so that it is as clear as possible
Thanks for your help Neff
import React, { Component } from 'react';
import { CardText, Card,Row, Col, CardTitle, Button } from 'reactstrap';
import axios from 'axios'
const entrypoint = process.env.REACT_APP_API_ENTRYPOINT+'/api';
class AdminPage extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
message: {
to: '',
body: 'hola amigo :)'
},
submitting: false,
error: false
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(event) {
event.preventDefault();
this.setState({ submitting: true });
fetch('/api/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state.message)
})
.then(res => res.json())
.then(data => {
if (data.success) {
this.setState({
error: false,
submitting: false,
message: {
to: '',
body: ''
}
});
} else {
this.setState({
error: true,
submitting: false
});
}
});
}
// rest of the component
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
getRandom = async () => {
const res = await axios.get(
entrypoint + "/alluserpls"
)
this.setState({ data: res.data })
}
componentDidMount() {
this.getRandom()
}
render() {
let datas = this.state.data.map(datass => {
const status = JSON.parse(localStorage.getItem("validated-order")||"{}")[datass.id];
return (
<div>
< Col sm="12" key={datass.id} className="wtfFuHereIsForOnlyBackGroundColorForCol12Nice">
<div key="a">
<Card body className="yoloCardBody">
<CardText> Téléphone {datass.phone}</CardText>
<form
onSubmit={this.onSubmit}
className={this.state.error ? 'error sms-form' : 'sms-form'} >
<div>
<input
type="tel"
name="to"
id="to"
value={this.state.message.to}
onChange={this.onHandleChange}
/>
</div>
<Button className="buttonForLancerMaybe" type="submit" disabled=
{this.state.submitting}>SMS</Button>
</form>
</Card>
</div>
</Col>
</div>
)
})
return (
<div> <div>
<div>
{datas}
</div>
</div>
</div>
<div className="box">
</div>
</div>
)
}
}
export default AdminPage
So I guess this little change in your code will help you, separating the logic and making a new component for your form section would be your solution. say we have a component called "SmsForm" so first, you need to import it in your current component:
import SmsForm from "../SmsForm/Loadable";
and then you pass your phone number as a prop to this SmsForm like this:
let datas = this.state.data.map(datass => {
const status = JSON.parse(localStorage.getItem("validated-order") || "{}")[datass.id];
return (
<div>
< Col sm="12" key={datass.id} className="wtfFuHereIsForOnlyBackGroundColorForCol12Nice">
<GridLayout className="GridlayoutTextOnlyForGridOuiAndHeigthbecauseHeigthWasBug" layout={layout} cols={12} rowHeight={30} width={1200}>
<div key="a">
<Card body className="yoloCardBody">
<CardText> Téléphone {datass.phone}</CardText>
<SmsForm phone={datass.phone}/>
</Card>
</div>
</GridLayout>
</ Col>
</div>
)
})
and SmsForm would be sth like this:
import React from 'react';
...
export class SmsForm extends React.Component {
constructor(props) {
super(props);
this.state = {
message: {
to: props.phone,
body: 'hola amigo :)'
},
submitting: false,
error: false
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(event) {
event.preventDefault();
this.setState({ submitting: true });
fetch('/api/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state.message)
})
.then(res => res.json())
.then(data => {
if (data.success) {
this.setState({
error: false,
submitting: false,
message: {
to: '',
body: ''
}
});
} else {
this.setState({
error: true,
submitting: false
});
}
});
}
// rest of the component
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
render() {
return (
<form
onSubmit={this.onSubmit}
className={this.state.error ? 'error sms-form' : 'sms-form'} >
<div>
<input type="tel" name="to" id="to" value={datass.phone} onChange={e => this.onHandleChange(e, e.target.value)}/>
</div>
<Button className="buttonForLancerMaybe" type="submit" disabled=
{this.state.submitting}>SMS</Button>
</form>
);
}
}
export default SmsForm;

Class properties must be methods. Expected '(' but instead saw '='

I have a react app, and I have this code, but it looks like the fetchdata m ethod is full of syntax errors, the first one shown on the title of the question.
Whats wrong with the method?
import React, { Component } from 'react';
import { Row, Col } from 'antd';
import PageHeader from '../../components/utility/pageHeader';
import Box from '../../components/utility/box';
import LayoutWrapper from '../../components/utility/layoutWrapper.js';
import ContentHolder from '../../components/utility/contentHolder';
import basicStyle from '../../settings/basicStyle';
import IntlMessages from '../../components/utility/intlMessages';
import { adalApiFetch } from '../../adalConfig';
const data = {
TenantId: this.this.state.tenantid,
TenanrUrl: this.state.tenanturl,
TenantPassword: this.state.tenantpassword
};
const options = {
method: 'post',
data: data,
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
};
export default class extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this);
this.handleChangeTenantPassword = this.handleChangeTenantPassword.bind(this);
this.handleChangeTenantId= this.handleChangeTenantId.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeTenantUrl(event){
this.setState({tenanturl: event.target.value});
}
handleChangeTenantPassword(event){
this.setState({tenantpassword: event.target.value});
}
handleChangeTenantId(event){
this.setState({tenantid: event.target.value});
}
handleSubmit(event){
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
fetchData();
}
fetchData = () => {
adalApiFetch(fetch, "/tenant", options)
.then(response => response.json())
.then(responseJson => {
if (!this.isCancelled) {
this.setState({ data: responseJson });
}
})
.catch(error => {
console.error(error);
});
};
upload(e) {
let data = new FormData();
//Append files to form data
let files = e.target.files;
for (let i = 0; i < files.length; i++) {
data.append('files', files[i], files[i].name);
}
let d = {
method: 'post',
url: API_SERVER,
data: data,
config: {
headers: {
'Content-Type': 'multipart/form-data'
},
},
onUploadProgress: (eve) => {
let progress = utility.UploadProgress(eve);
if (progress == 100) {
console.log("Done");
} else {
console.log("Uploading...",progress);
}
},
};
let req = axios(d);
return new Promise((resolve)=>{
req.then((res)=>{
return resolve(res.data);
});
});
}
render(){
const { data } = this.state;
const { rowStyle, colStyle, gutter } = basicStyle;
return (
<div>
<LayoutWrapper>
<PageHeader>{<IntlMessages id="pageTitles.TenantAdministration" />}</PageHeader>
<Row style={rowStyle} gutter={gutter} justify="start">
<Col md={12} sm={12} xs={24} style={colStyle}>
<Box
title={<IntlMessages id="pageTitles.TenantAdministration" />}
subtitle={<IntlMessages id="pageTitles.TenantAdministration" />}
>
<ContentHolder>
<form onSubmit={this.handleSubmit}>
<label>
TenantId:
<input type="text" value={this.state.tenantid} onChange={this.handleChangeTenantId} />
</label>
<label>
TenantUrl:
<input type="text" value={this.state.tenanturl} onChange={this.handleChangeTenantUrl} />
</label>
<label>
TenantPassword:
<input type="text" value={this.state.tenantpassword} onChange={this.handleChangeTenantPassword} />
</label>
<label>
Certificate:
<input onChange = { e => this.upload(e) } type = "file" id = "files" ref = { file => this.fileUpload } />
</label>
<input type="submit" value="Submit" />
</form>
</ContentHolder>
</Box>
</Col>
</Row>
</LayoutWrapper>
</div>
);
}
}
You have written your fetchData method in the form of a class field which is not part of the language yet. You could add the Babel plugin proposal-class-properties or a preset that has it, like the stage 2 preset. (Note that the class field proposal is a finished stage 4 proposal as of April 2021.)
If you don't want to configure Babel, you could bind the method in your constructor instead, like you have done with your other methods:
export default class extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this);
this.handleChangeTenantPassword = this.handleChangeTenantPassword.bind(this);
this.handleChangeTenantId= this.handleChangeTenantId.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.fetchData = this.fetchData.bind(this);
}
fetchData() {
adalApiFetch(fetch, "/tenant", options)
.then(response => response.json())
.then(responseJson => {
if (!this.isCancelled) {
this.setState({ data: responseJson });
}
})
.catch(error => {
console.error(error);
});
}
// ...
}
Have you defined the fetchdata variable previously?If not, perhaps you should do it in the current line:
var fetchdata = () => { ...

Categories

Resources