how to set url in another input after upload file in reactjs - html

I am working with react with axios. i am uploading a file in react and i want to set url in another input after file upload but i am unable to get value. in console i am getting value properly but issue in input field. currently i m doing with different method.
i want uploaded file url in id="uploadRhp". please help if anybody know.
import React, { Component } from 'react';
import axios from "axios";
class TradeImportComponent extends React.Component<{},any>{
// API Endpoints
custom_file_upload_url = `https://exaample.com/api/ipo/document/upload`;
canvas: any;
// state
constructor(props) {
super(props);
this.canvas = React.createRef()
this.state = {
image_file: null,
image_preview: '',
}
}
// Image Preview Handler
handleImagePreview = (e) => {
let image_as_base64 = URL.createObjectURL(e.target.files[0])
let image_as_files = e.target.files[0];
this.setState({
image_preview: image_as_base64,
image_file: image_as_files,
})
}
// Image/File Submit Handler
handleSubmitFile = () => {
if (this.state.image_file !== null){
let formData = new FormData();
formData.append('ipoName', 'tata');
formData.append('document', this.state.image_file);
axios.post(
this.custom_file_upload_url,
formData,
{
headers: {
// "Authorization": "YOUR_API_AUTHORIZATION_KEY_SHOULD_GOES_HERE_IF_HAVE",
"Content-type": "multipart/form-data",
},
}
)
.then(res => {
console.log(`Success` + res.data.response);
var json= JSON.parse(JSON.stringify(res.data.response));
console.log(json);
console.log(json.url);
console.log(this.canvas.current.value);
this.canvas.current.value=json.url;
console.log(this.canvas.current.value);
})
.catch(err => {
console.log(err);
})
}
}
// render from here
render() {
return (
<div>
{/* image preview */}
<img src={this.state.image_preview} alt="image_preview" width="100%"/>
{this.state.url}
{/* image input field */}
<input
type="file"
onChange={this.handleImagePreview}
/>
<input type="hidden" name="logo" id="uploadlogo"/>
<input type="hidden" name="rhp" value="test#1234567" ref={this.canvas} id="uploadRhp"/>
<input type="hidden" name="financial_Pdf" id="uploadfinancial"/>
<label>Upload file</label>
<input type="submit" onClick={this.handleSubmitFile} value="Submit"/>
<ul>
</ul>
</div>
);
}
}
export default TradeImportComponent;

Use setstate in axios response store the response in state
// state
constructor(props) {
super(props);
this.canvas = React.createRef()
this.state = {
image_file: null,
image_preview: '',
uploadURL:''
}
}
handleSubmitFile = () => {
if (this.state.image_file !== null){
let formData = new FormData();
formData.append('ipoName', 'tata');
formData.append('document', this.state.image_file);
return axios.post(
this.custom_file_upload_url,
formData,
{
headers: {
// "Authorization": "YOUR_API_AUTHORIZATION_KEY_SHOULD_GOES_HERE_IF_HAVE",
"Content-type": "multipart/form-data",
},
}
)
.then(res => {
console.log(`Success` + res.data.response);
var json= JSON.parse(JSON.stringify(res.data.response));
//use setstate
setState({uploadURL:json.url)
})
.catch(err => {
console.log(err);
})
}
}
//in JSX render
<Input value={this.state.uploadUrl}/>

Related

How to send formdata with other data in MERN App?

I want to save a image to cloudiary from Nodejs in a Mern Application. I have data in such a way that formdata is a field.
I want to send multiple fields from frontend with formdata but whenever I am trying to assign the formdata to my object, it is getting assigned as empty object {}
Code for Component where I have 2 more fields apart from formdata or file input.
import axios from "axios";
import React, { useState } from "react";
function About({ setAboutInfo, touched = false, setInvalid }) {
const [about, setAbout] = useState({
name: "",
objective: "",
imageUrl: {},
});
const handleChange = (e) => {
var formData = new FormData();
if (e.target.name == "imageUrl") {
formData.append("imageUrl", e.target.files[0]);
setAbout({ ...about, imageUrl: formData });
} else setAbout({ ...about, [e.target.name]: e.target.value });
setAboutInfo(about);
if (!(about.name && about.objective)) {
setInvalid((prev) => ({ ...prev, about: true }));
} else {
setInvalid((prev) => ({ ...prev, about: false }));
}
};
return (
<div className="ext-container row pb-0">
<form encType="multipart/form-data">
<div className="col-md-6">
<label className="my-labels" htmlFor="">
Name
</label>
<input
value={about.name}
name="name"
type="text"
onChange={handleChange}
className={"my-inputs "}
placeholder="Enter complete name"
/>
</div>
<div className="col-md-6">
<label className="my-labels" htmlFor="">
Profile Pic
</label>
> <input
> name="imageUrl"
> type="file"
> accept="image/*"
> onChange={handleChange}
> className={"my-inputs "}
> placeholder="Choose profile pic"
> />
</div>
<div className="col-md-12">
<label className="my-labels" htmlFor="">
Objective
</label>
<textarea
name="objective"
value={about.objective}
type="text"
onChange={handleChange}
className={"my-inputs "}
rows={4}
placeholder="Enter Objective"
></textarea>
</div>
</form>
</div>
);
}
export default About;
I am sending this data to parent component from setAboutInfo method.
Parent component making request to backend
const saveData = (e) => {
e.preventDefault();
setTouched(true);
console.log({
...about,
});
// console output
**
{
name: 'Jack', objective: "Jack's objective", imageUrl: FormData}
imageUrl: FormData {}
name: "Jack"
objective: "Jack's objective"
[[Prototype]]: Object
}
**
axios
.post(
"/resume",{...about})
.then((response) => {
if (response.status == 201) {
console.log(response);
success("Data saved successfully");
}
})
.catch((e) => console.log(e));
};
In backend I am getting this as body of Post request
{ name: 'Jack', objective: "Jack's objective", imageUrl: {} }
You have to append whole body in formdata and send send form data to the api.
const saveData = (e) => {
e.preventDefault();
setTouched(true);
console.log({
...about,
});
// console output
**
{
name: 'Jack', objective: "Jack's objective", imageUrl: FormData}
imageUrl: FormData {}
name: "Jack"
objective: "Jack's objective"
[[Prototype]]: Object
}
**
let formData = new FormData();
formData.append("imageUrl", about.imageUrl);
formData.append("name", about.name);
formData.append("objective", about.objective);
axios
.post(
"/resume",formData )
.then((response) => {
if (response.status == 201) {
console.log(response);
success("Data saved successfully");
}
})
.catch((e) => console.log(e));
};
For onchange method don't save in form data.
const handleChange = (e) => {
if (e.target.name == "imageUrl") {
setAbout({ ...about, imageUrl: e.target.files[0]});
} else setAbout({ ...about, [e.target.name]: e.target.value });
setAboutInfo(about);
if (!(about.name && about.objective)) {
setInvalid((prev) => ({ ...prev, about: true }));
} else {
setInvalid((prev) => ({ ...prev, about: false }));
}
};

How do I edit a task in a react/mysql application?

So I am making a ToDo app but so far I can just create a task, or delete it. Right now I am trying to make another feature where I can edit the specific task by clicking the edit button and then it will change the task into an input area where i can edit the task name. Can someone help me with this? How it looks right now is displayed below.
My Code right now is below:
import React, { Component } from 'react';
import axios from "axios";
export default class TaskInput extends Component {
constructor(props) {
super(props)
this.state = {
task: " ",
allTasks: [],
strikeThrough: {textDecoration:""}
}
}
changeHandler = (event) => {
console.log(event.target.value)
this.setState({
task: event.target.value,
})
}
handleStrikethrough = (completed, id) => {
// !completed ? this.setState({strikeThrough:{textDecoration: "line-through"}}) : this.setState({strikeThrough:{textDecoration:""}})
// if (!completed) {
// console.log("not completed", !completed)
// this.setState({strikeThrough:{textDecoration: "line-through"}});
// axios.put("/api/task", {
// completed: !completed
// }, id).then(response => console.log(response))
// } else {
// this.setState({strikeThrough:{textDecoration:""}})
// axios.put("/api/task", {
// completed: !completed
// }, id).then(response => console.log(response))
// }
}
handleDelete = (taskId) => {
axios.delete("/api/task/" + taskId).then(data => {
console.log("You deleted the task with an id of ", data)
})
window.location.reload();
}
handleTaskEdit = () => {
console.log("edit button worked")
}
submitHandler = (event) => {
event.preventDefault() //to prevent page refresh
console.log()
fetch("/api/task", {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(this.state),
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err))
this.setState({
task: ""
})
window.location.reload()
}
componentDidMount() {
console.log("component did mount")
const self = this;
axios.get("/api/tasks").then(function (data) {
self.setState({
allTasks: data.data
})
// console.log(self.state.allTasks[0].task)
})
}
render() {
const {strikeThrough, task, allTasks} = this.state; //destructuring the state
return (
<div>
<form onSubmit={this.submitHandler} >
<label style={{ margin: "5px 0px" }}>Create a Task:</label>
<input value={this.state.task} onChange={this.changeHandler} style={{ width: "100%" }}></input>
<input style={{ padding: "5px", marginTop: "5px" }} type="submit"></input>
</form>
<hr></hr>
<br></br>
<ul>
{this.state.allTasks.map(task => (
<li style={strikeThrough} onClick={()=>this.handleStrikethrough(task.completed, task.id)} className="tasks">{task.task}
<button onClick = {() => this.handleDelete(task.id)}>x</button>
<button onClick={this.handleTaskEdit}>edit</button>
</li>
)
)}
</ul>
</div>
)
}
}
You could set task ID on its corresponding Edit button, then when clicking Edit button get the task using ID and sending that task to an edit component.
First of all handleTaskEdit, here you set task name to the task property and set ID of editable task:
handleTaskEdit = id =>
this.setState({ task: this.state.allTasks.find(el => el.id === id).task })
secondly, create two new methods, createTask and updateTask:
createTask = () => {
fetch("/api/task", {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({task: this.state.task}),
})
.then(res => res.json())
.then(data => this.setState({
task: '',
allTasks: [...this.state.allTasks, data]}))
.catch(err => console.log(err))
}
updateTask = () => {
fetch("/api/task", {
method: "PATCH",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({task: this.state.task, id: this.state.editableTaskId}),
})
.then(res => res.json())
.then(data => this.setState({
task: '',
editableTaskId: null,
allTasks: this.state.allTasks.map(el =>
el.id === data.id ? data : el)})) // Or take new name and id from state
.catch(err => console.log(err))
}
and finally you need to update submitHandler and handleDelete:
submitHandler = () => {
if (this.state.editableTaskId) {
this.updateTask();
} else {
this.createTask()
}
}
handleDelete = (taskId) => {
axios.delete("/api/task/" + taskId).then(data => {
this.setState({allTasks: this.state.allTasks.filter(el =>
el.id !== data.id
)})
})
}
Here's the approach:
Have a state variable called editTaskID and keep the default value as null. On the edit button set the functionality of handleTaskEdit in such a way that it sets the editTaskID to that particular task ID on which edit button was clicked.
In the map function where you are rendering the list items for tasks, add a condition such as:
{this.state.allTasks.map(task =>
(
<li style={strikeThrough}
onClick={()=>this.handleStrikethrough(task.completed, task.id)}
className="tasks">
{
this.editTaskID
?<input
value={this.state.editTaskName}
/*supposing editTaskName to be state variable that stores
the edit textfield content.*/
onChange={this.changeEditHandler} style={{ width: "80%" }}>
</input>
:task.task
}
<button onClick = {() => this.handleDelete(task.id)}>x</button>
<button onClick={this.handleTaskEdit}>edit</button>
</li>
)
)
}
This will now check the condition whether the editTaskID has been set to null or not while rendering. In case if it is null, all your tasks will come as a plain text else it will come in form of a text box. You can also add the value to the edit task input field with the help of allTasks[editTaskID].
On the handleTaskEdit function of the edit button, make sure to set the allTasks[editTaskID] to the value editTaskName and also to set the state variable editTaskID to null.
Call the necessary backend endpoint to reflect the changes in your database as well.
I hope it helps. Thanks.

Trouble display name property from axios fetched json object

https://codesandbox.io/s/currying-voice-toq9t - I am trying to save the json object into the component state, then render the name into the browser.
getProfile() {
axios
.get(
"https://cors-anywhere.herokuapp.com/" +
"https://phantombuster.s3.amazonaws.com....."
)
.then(response => {
this.setState({
profile: {
name: response.data.name
}
});
})
.catch(error => this.setState({ error, isLoading: false }));
}
Your Response data is an array form so,You need to give Index.I hope it will helps you.
getProfile() {
axios
.get(
"https://cors-anywhere.herokuapp.com/" +
"https://phantombuster.s3.amazonaws.com/YRrbtT9qhg0/NISgcRm5hpqtvPF8I0tLkQ/result.json"
)
.then(response => {
this.setState({
profile: {
name: response.data[0].name
}
});
})
.catch(error => this.setState({ error, isLoading: false }));
}
The response.data is an array where in first position there is the information that you are looking for, so the setState should be like this:
this.setState({
profile: {
name: response.data[0].name
}
});
or
const [obj] = response.data;
this.setState({
profile: {
name: obj.name
}
});
Your response.data returns an array.so you need to traverse it inside a loop.
import React from "react";
import ReactDOM from "react-dom";
import axios from "axios";
export class Profile extends React.Component {
constructor(props) {
super(props);
this.state = { profile: [] };
}
componentDidMount() {
this.getProfile();
}
getProfile() {
axios
.get(
"https://cors-anywhere.herokuapp.com/" +
"https://phantombuster.s3.amazonaws.com/YRrbtT9qhg0/NISgcRm5hpqtvPF8I0tLkQ/result.json"
)
.then(response => {
console.log("response: ", response)
this.setState({
profile: response.data
});
})
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
let { name } = this.state.profile;
const { error } = this.state;
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Profile</h1>
{error ? <p>{error.message}</p> : null}
</header>
<div className="App-feeds" />
<div className="panel-list">
{this.state.profile.map((element) => <p>First Name: {element.name}</p>)}
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Profile />, rootElement);

how to pass data from save function to server in MySQL using API call

I am new to Angular 2&4, when I am trying to connect angular4 with MySQL using HTTP.post method. The values are not passing to API/save in server.js. Can anyone please help how to insert data into MySQL from angular4.
I am getting an error at server.js.
app.component.html
<main class="content">
<h2>Login</h2>
<form>
<div class="form-group">
<label for="username">UserName: </label>
<input type="text" name="username" [(ngModel)]="person.username" class="form-control" required />
</div>
<div class="form-group">
<label for="password">Password: </label>
<input type="text" name="password" [(ngModel)]="person.password" class="form-control" required />
</div>
<div class="form-group">
<button class="btn btn-primary" (click)="save()" >Save</button>
</div>
</form>
</main>
app.component.js
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { ActivatedRoute} from '#angular/router';
import { Location } from '#angular/common';
import { Http, Headers, RequestOptions } from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public person: any;
public constructor(private http: Http, private route: ActivatedRoute, private location: Location) {
this.person = {
"username": "",
"password": ""
};
}
public ngOnInit() {}
public save() {
console.log("save function starts");
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
console.log("save function middle"+ JSON.stringify(this.person));
this.http.post("http://localhost:3000/api/save", JSON.stringify(this.person), options)
.map(result => result.json())
.subscribe(results => {
this.location.back();
}, error => {
console.error(error);
});
}
}
server.js
var app = express();
var path = require("path");
var postsModel = require('./models/posts');
var bodyParser = require('body-parser');
var mysql = require('mysql2');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'admin',
database: 'Speckle'
});
var app = express();
connection.connect(function(err){
if(!err) {
console.log("Database is connected ... nn");
} else {
console.log("Error connecting database ... nn");
}
});
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post("/api/save",function(req, res) {
console.log("request"+ req.body.username);
postsModel.save(req.body);
});
app.use(express.static(path.join(__dirname, "")));
app.listen(3000);
posts.js
var database = require('./database');
exports.save = function (params) {
return database.query("INSERT INTO login SET ?", params)
.then(function (result) {
console.log("save");
return result.insertusername;
});
};
database.js
var mysql = require('mysql2');
var connection;
exports.init = function (config) {
connection = mysql.createConnection(config);
};
exports.query = function (sql, params) {
return new Promise(function (resolve, reject) {
console.log("SQL statement" + sql);
console.log("sql"+sql +""+"params" +params.username+params.password);
connection.query(sql, params, function(error, result) {
if (error) {
return reject(error);
}
resolve(result);
});
});
};
instead of this
<button class="btn btn-primary" (click)="save()" >Save</button>
you can go with this.
<button class="btn btn-primary" (click)="save(person)" >Save</button>
public save(person) {
console.log("save function starts");
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
console.log("save function middle"+ JSON.stringify(this.person));
this.http.post("http://localhost:3000/api/save", JSON.stringify(person), options)
.map(result => result.json())
.subscribe(results => {
this.location.back();
}, error => {
console.error(error);
});
}
The problem here is that you are performing stringify JSON data and at the server side you doesn't parse it to the JSON. However at requests you don't have to stringify it becasuse you can just sent JSON data without any errors. But If you want to send stringified JSON you have to parse it to JSON to use it as param.login or param.password, without this you are just refering to the string to non-existing property. So after you send data you should perform on data JSON.parse().
try this
public save() {
console.log("save function starts");
let data = this.person;
this.http.post("http://localhost:3000/api/save",data)
.map(result => result.json())
.subscribe(results => {
this.location.back();
}, error => {
console.error(error);
});
}

I can't fetch react form

Hi I try to make simple contact from in react, but I stuck on fetch() method.
This is my code. I have no idea what is wrong.
FrontEnd
export default class ContactForm extends React.Component<IContactFormProps, any> {
constructor(props) {
super(props);
// local state
this.state = {
tl: new TimelineMax({paused: true, delay: 1}),
name: "",
email: "",
subject: "",
message: "",
sent: false,
}
this.handleOnSubmit = this.handleOnSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleChange = this.handleChange.bind(this);
this.startAnimation = this.startAnimation.bind(this);
}
handleOnSubmit(e) {
console.log("ContactForm->handleOnSubmit(e).");
e.preventDefault();
let formData = new FormData();
formData.append(name, this.state.name);
console.log("formData: " + formData);
fetch('/contact', {
method: 'POST',
body: formData
})
.then((response) => {
console.log("response: " + response);
console.log("response.ok: " + response.ok);
return response.json();
})
.then((responseJson) => {
console.log("responseJson: " + responseJson);
})
.catch((error) => {
console.log("error from fetch: " + error);
});
}
handleClearForm(e) {
console.log("ContactForm->handleClearForm(e).");
// e.preventDefault();
}
handleChange(event) {
const target = event.target;
const name = event.target.name;
const value = event.target.value;
this.setState({
[name]: value
});
// console.log("event.target.value: " + event.target.value);
// this.setState({value: event.target.value});
}
startAnimation() {
console.log("ContactForm->startAnimation().");
}
componentDidMount() {
this.startAnimation();
}
componentWillUnmount() {
}
render() {
return (
<form className="contact-form-cnt"
onSubmit={ this.handleOnSubmit }>
<div className="top-row">
<input type="text" name="name" placeholder="Name"
className="name" ref="name"
value={this.state.name} onChange={this.handleChange}/>
<input type="text" name="email" placeholder="Em#il"
className="email" ref="email"
value={this.state.email} onChange={this.handleChange}/>
</div>
<input type="text" name="subject" placeholder="Subject"
className="subject" ref="subject"
value={this.state.subject} onChange={this.handleChange}/>
<textarea name="message" placeholder="Write Your message here."
className="message" ref="message"
value={this.state.message} onChange={this.handleChange}></textarea>
<button type="submit" name="submit"
className="submit" ref="Send"
onClick={ this.handleClearForm }>Send</button>
</form>
);
};
};
BackEnd
'use strict';
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const winston = require('winston');
const distPath = path.join(__dirname, '../dist');
const indexFileName = 'index.html';
const app = express();
const PORT = process.env.PORT || 8080;
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(express.static(distPath));
app.get('*', (req, res) => res.sendFile(path.join(distPath, indexFileName)));
app.post("/contact", (req, res) => {
try {
console.log("mail sending succes!");
}
catch ( error ) {
console.log("mail sending failure!");
}
});
app.listen(PORT, (err) => {
if (err) {
winston.error(err);
return;
}
winston.info(`Listening on port ${PORT}`);
});
URL:
http://localhost:8080/contact
and error
POST http://localhost:8080/contact 404 (Not Found)
I think it's something with url, but I'am out of ideas. Any sugestions?
try something like this:
app.post("/contact", (req, res) => {
res.json({"foo": "bar"});
});
this way you are setting an json object as result. Let me know if works.