React upload and display image - reactjs

I don’t understand how to upload a photo correctly and then upload it to the page.
I'm a beginner, can you please tell me what I did wrong?
const [photo, setPhoto] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
const users = {name, email, phone, position, photo}
setIsPending(true);
fetch("http://localhost:8000/users", {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify(users)
}).then(() => {
console.log('well');
setIsPending(false);
})
}
<form className="form" onSubmit={handleSubmit}>
<UploadFile
name="file"
onChange={(e) => setPhoto(e.target.files[0])}
value= {photo}
/>
<Button type="submit"/>
</form>

First of all you have to find a service that allows you to upload a file.
for example: https://api.imgur.com/endpoints/image/
there instructions inside.
However if you want to use fetch method I will give you an example how it should look like.
const handleSubmission = () => {
const formData = new FormData();
formData.append('File', selectedFile);
fetch(
'https://freeimage.host/api/1/upload?key=<YOUR_API_KEY>',
{
method: 'POST',
body: formData,
}
)
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});
};
};
After recieving response from api service which is this part
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});
You can set your state with the response url like this.
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
setPhoto(result.data.imageurl)
})
.catch((error) => {
console.error('Error:', error);
});
In the end you can use that image anywhere you want.
<img src={photo} />

Related

State is being changed, but display not updating

I've seen quite a few posts about this, but none of the solutions seem to work for me.
I have a render method that is being mapped to list the different sections stored in a state(this part works as expected):
render() {
return (
<ThemeProvider theme={theme}>
<Div>
<hr />
<div>
{this.state.sections.map(section => (
<div
className="mb-3"
key={section.section_title}
>
<h3>{section.section_title}</h3>
</div>
))}
</div>
)
}
However, I have a modal that allows you to create a new section by giving it a name and clicking submit. That does create it and add it to my database table as expected. But, then when I run the method to pull that data down, and change the state to include the new section, it works, and does indeed change the state to include the new section. But it does not update the display unless I reload the page. Can anyone see why?
getProjectSections(projId) {
fetch(API_URL + `/billingcalculator/sections/distinct/${projId}`)
.then((res) => {
if (!res.ok) {
throw new Error()
}
return res.json()
})
.then((result) => {
let listedSections = [...result];
this.setState({ sections: listedSections });
})
.catch((error) => {
console.log(error);
})
}
the getProjectSections() runs when you click the submit button a creating a new section which runs this:
handleSectionCreateSave() {
fetch(API_URL + `/billingcalculator/section/create`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
sectionTitle: this.state.newSectionTitle
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
.then(this.getProjectSections(this.props.billProjId))
.then(this.setState({ showSectionModal: false }))
.catch((err) => console.log(err));
}
You are calling state updates before request happens:
handleSectionCreateSave() {
fetch(API_URL + `/billingcalculator/section/create`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
sectionTitle: this.state.newSectionTitle
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
// you called these function now, instead after fetch
// use () =>
.then(() => this.getProjectSections(this.props.billProjId))
.then(() => this.setState({ showSectionModal: false }))
.catch((err) => console.log(err));
}

How to set fetch data to text field in react-native function component

I am learning react-native and have a question about fetching data and passing them to a text component.
I fetched my data from my node.js back-end but don't know how to pass this data to component. Below is the code that i have tried so far.
const TableView = () => {
const [details, setDetails] = useState('');
const getUserData = async () => {
fetch('https://----.herokuapp.com/getIncomePerUser', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: data,
month: value,
}),
})
.then(response => response.json())
.then(response => {
console.log('Test');
console.log(response);
const array = response;
for (const i of array) {
const total = i.total;
setDetails(total);
console.log(total);
}
})
.catch(err => {
console.log(err);
});
});
};
useEffect(() => {
getUserData();
}, []);
return (
<Text Value={details}></Text> //I need to set my fetch data this text component
)
}
if you have an array of values and you want to show them you can use:
const TableView = () => {
const [details, setDetails] = useState('');
const getUserData = async () => {
fetch('https://----.herokuapp.com/getIncomePerUser', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: data,
month: value,
}),
})
.then(response => response.json())
.then(response => {
setDetails(response.map(r => r.total));
})
.catch(err => {
console.log(err);
});
});
};
useEffect(() => {
getUserData();
}, []);
return (<>
{details.map((d, i) => <Text key={i}>{d}</Text>)}
</>)
}
if you have a single value just replace your text component with:
<Text>{details}</Text>

fetch success returns a promise

I have implemented a external API function to return text/html when a button is clicked. But is doesn't seem return the data. instead a promise is returned.
<TouchableOpacity onPress={() => getData() }>
<Text style={styles.button}>Register</Text>
</TouchableOpacity>
the fetch function
const getData= () => {
let formData = new FormData();
formData.append("name", 'ABC');
formData.append("age", 35)
fetch(API_URL, {
method: 'POST',
body: formData,
}).then(response => {
console.log('success');
console.log(JSON.stringify(response.text()))
}).catch(error => {
console.log('error');
console.error(JSON.stringify(response));
})
}
I want only the html/text response
You'll need to handle the response.JSON first:
const getData= () => {
let formData = new FormData();
formData.append("name", 'ABC')
formData.append("age", 35)
fetch(API_URL, {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(response => {
console.log(response)
})
.catch(error => {
console.log('error')
})
}
Check out this documentation for more details.

How to post 2 APIs at a time while doing on submit method using reactjs?

I'm new to react, i'm doing a small project where i have created a form and i want to add file also. Form having one API and for uploading files having another api.
handleSubmit = e => {
e.preventDefault();
const { firstName, LastName, phoneNumber} = this.state;
const data = {
firstName,
lastName,
phoneNumber
};
axios.post(`/api/Form`, data, {
headers: { 'Content-Type': 'application/json' }
})
.then(res => {
console.log(res)
console.log(res.data);
})
.catch((err) => {
console.log(err)
})
for files:
uploadFile = (files) => {
var formData = new FormData();
files.map((file, index) => {
formData.append(`file${index}`, file);
});
fetch('/api/uploadFiles', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(success => {
})
.catch(error => console.log(error)
);
}
I couldn't able to figure it out how to write both apis in submit method. Can anyone help me in this query? I'm not sure how to give 2 apis in submit method.
Assign your formData to State
uploadFile = (files) => {
var formData = new FormData();
files.map((file, index) => {
formData.append(`file${index}`, file);
});
this.setState({file:formData});
}
Then Post your 2 API's in handleSubmit
handleSubmit = e => {
e.preventDefault();
const { firstName, lastName, phoneNumber, file} = this.state;
const data = {
firstName,
lastName,
phoneNumber
};
axios.post(`/api/Form`, data, {
headers: { 'Content-Type': 'application/json' }
}).then(res => {
console.log(res)
console.log(res.data);
}).catch((err) => {
console.log(err)
});
if(file) {
fetch('/api/uploadFiles', {
method: 'POST',
body: file,
}).then(response => response.json()).catch(error => console.log(error));
}
}

How can I dynamically rerender my api to my webpage?

So I have this api and I am making a get request in my ComponentDidMount() to dynamically render it to my page and it works. The issue I am facing is when I make a post request to add items to the list, it does not show on my webpage unless I refresh it. The backend is my data.json so I don't know if that is the problem but essentially when I make a post request, I am adding data to my data.json and I want that to rerender on my page without me refreshing it.
componentDidMount() {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
// console.log(Object.keys(item)[0])
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
// console.log(this.state.titles)
// console.log(this.state.data)
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res)
})
.catch(err => console.log(err));
}
render() {
let board = this.state.data.map((item, key) => {
return <WorkBoardContainer
key={key}
title={item[this.state.titles[key]]["title"]}
listItems={item[this.state.titles[key]]["list"].map((i) => {
return i["title"]
})}
/>
})
return (
<div className={classes.App}>
<AddButton addListItemHandler={this.addListItemHandler}/>
{board}
</div>
);
}
Try moving the fetching part as a seperate function and call it again once the post request is done.
componentDidMount() {
// fetch data when component is mounted
this.fetchData();
}
fetchData = () => {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res);
// fetch data again once post is done.
this.fetchData();
})
.catch(err => console.log(err));
}

Resources