How to extract localstorage values in reactjs - javascript

I am using form in reactjs. I stored user data in localstorage now I want to upload file and i want to store file key with userID which is already stored in localstorage. With localstorage.getItem('user') I am able to show user values but did not use in key, when i display user values in console it give me message with undefined. Could you please help me how i can set key with userid.
Code
handleUpload = e => {
const reader = new FileReader();
const storeUser = JSON.parse(localStorage.getItem('user'));
reader.onload = function(upload) {
fetch(`http://...../s3/uploadtoaws`, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({
userId: storeUser._id,
type: 'employee',
content: upload.target.result,
key: this.userId,
oldKey: '',
}),
})
.then(response => response.json())
.then(res => {
console.warn(res);
})
.done();
};
reader.readAsDataURL(e.file.originFileObj);
};

Use window object to store your data if it is in-incentive
Like,
// Store like this..
window.user = {"_id": 1, "userName": "Bhavin00"};
// Use like this..
console.log(window.user);
or you can use npm package like :- reactjs-localstorage

let user = JSON.parse(localStorage.getItem('user'));
const { id: userId } = user;
Now you can use userId in the above request you shared.

Related

Required request part 'image' is not present with React and Spring Boot

I am getting "MissingServletRequestPartException: Required request part 'studentImg' is not present", It works fine with Postman but not with React. I am trying to call a end point in a Spring boot restful API.
Backend Controller Code:
#PostMapping("/add")
public ResponseEntity<StudentFile> addStudentImg(HttpServletRequest request, #RequestParam("studentImg") MultipartFile studentImg) {
boolean isStudent = (Boolean) request.getAttribute("isStudent");
if(false == isStudent) {
throw new EtAuthException("Only Student can add their image.");
} else {
Long addedBy = (Long) request.getAttribute("studentId");
StudentFile studentFile = studentFileService.addStudentImg(studentImg, addedBy);
return new ResponseEntity<>(studentFile, HttpStatus.CREATED);
}
}
React Components' Code Snippets:
handleStudentImgChange(event) {
this.setState({ studentImg: event.target.files[0] });
}
handleOnSubmit(event) {
event.preventDefault();
const { studentImg } = this.state;
this.props.addStudentImg(studentImg);
this.setState({ studentImg: null });
}
const mapDispatchToProps = (dispatch) => {
return {
addStudentImg: (studentImg) => {
dispatch(addStudentImgAction(studentImg));
},
};
export default connect(null, mapDispatchToProps)(AddStudentImgPage);
React Axios Call:
import axios from "axios";
const token = "...";
export const addStudentImg = (studentImg) => {
let bodyFormData = new FormData();
bodyFormData.append("studentImg", studentImg[0]);
const headers = {
Authorization: `Bearer ${token}`,
// Accept: "application/json",
"Content-Type": "multipart/form-data",
};
return axios
.request({
method: "POST",
url: "http://localhost:8080/api/studentfiles/add/",
data: bodyFormData,
headers: headers,
})
.then((res) => res.data);
};
The network log: enter image description here enter image description here
I'm unable to find any solution regarding that. Please give suggestions.
Thanks in Advance :D
You already set files[0] when you set
handleStudentImgChange(event) {
this.setState({ studentImg: event.target.files[0] });
}
then again, you are trying to access
bodyFormData.append("studentImg", studentImg[0]);
This, seems wrong, change this to
bodyFormData.append("studentImg", studentImg);
and see if it works..
First I changed these lines:
let bodyFormData = new FormData();
bodyFormData.append("studentImg", studentImg[0]);
With these:
const bodyFormData = new FormData();
const blob = new Blob([studentImg], {type: studentImg.type});
bodyFormData.append("studentImg", blob);
When I logged studentImg just above the bodyFormData, I get the response something like: {type: 'ADD_STUDENT_IMG', studentImg: File} where it was json object like this:
Then, I put thse lines and these are just working fine with it.
const bodyFormData = new FormData();
const blob = new Blob([studentImg.studentImg], {
type: studentImg.studentImg.type,
});
bodyFormData.append("studentImg", blob);
To understand how these lines are working:
Please read the FormData docs and also some additional information about how it's serialized over here.
If any queries, please ask. (P.S. prescriptionImg == studentImg for fig.)
Thanks :D

State not updating within a promised fetch (react)

I have a form with which i am sending data to my api. The data is used to create backend admin accounts and also create post entries. I need to post the data in a certain order to get some dynamic fields from the admin account to the post. For example:
create the admin account to make an id field
use the id field and apply to the post to create a unique link between admin account and post
Everything works apart from one state update that i'm trying to do after fetching the freshly created account:
// dont know what the ID will be as its dynamic
const [theID, setTheID] = useState('');
//Send the data to firstly create the admin account (works fine)
fetch('example.com/api/cockpit/saveUser', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
},
body: JSON.stringify({
user: {
user: firstname.toLowerCase()+surname.toLowerCase(),
name: firstname,
email: email,
password: password,
group: 'consumers',
}
})
})
.then(user => user.json())
// make next fetch a chain of the promise
// fetch all accounts but filter by email so will only return the right one
.then(()=>{
return fetch(`example.com/api/cockpit/listUsers&filter[email]=${email}`,{
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
}
})
})
.then((res) => {
return res.json();
})
.then((res)=>{
// the console log works fine
console.log(res[0]._id);
// the state returns undefined
setTheID(res[0]._id);
})
.catch((err)=>{
console.error(err);
})
//Then last fetch to make the post entry works fine ...
.then(()=>{
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
firstname: firstname,
surname: surname,
password: password,
email: email,
project_name: projectName,
project_template: tmp,
// expected to get the dynamic ID front the state
ass_consumer: theID,
slug: projectName.toLowerCase().replace(' ','') + '-rr',
username: firstname.toLowerCase()+surname.toLowerCase()
}
})
})
})
.then(user => user.json())
.then((user)=>{
setnewPage(user._id);
})
I've checked the console which shows up fine after fetching. All my other state changes are bound to the form inputs but i've never had this problem with updating state in a fetch before.
I've also tried creating a function that takes the email as an argument then returns the state change but no luck with that either.
Appreciate any help!
(using cockpit as my api)
EDIT
This is what the console log returns:
(i just need the _id)
{
user: "johndoe",
name: "john",
email: "john.doe#example.com",
active: true,
group: "consumers", 
_created: 1627039008,
_id: "60faa5203365618a38000035",
_modified: 1627039008,
}
You are most likely reading the state within the same operation ("too quickly"), so the state changes will not be reflected yet because the process to update React state is asynchronous.
You have 2 options to always get the most up to date state value:
Either use a reference to the state (check out this package)
Or use an "ugly" work-around taking the value from setState like this:
const [id, setId] = useState("")
setId("test")
console.log(id) // ""
// do this to get the up to date value, as the value
// in setState is always the most up to date one
let idVal
setId(current => {
idVal = current
return current
})
console.log(idVal) // "test"
So in your specific example, try this:
//Then last fetch to make the post entry works fine ...
.then(()=>{
let customerID
setTheID(current => {
customerID = current
return current
})
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
[...]
// use the customerID variable, not the state variable
ass_consumer: customerID,
[...]
}
})
})
})

How can I add my query parameter data -which I use in URL- to my response data?

I'm sending a request to get organization data's from API firstly, then ı getting another specific data's -which is "plants"- from another API with sending as a parameter organizationEIC property of my organization data which ı get in the first request. I am doing this to get for each plants of each organizations. What ı want to do is, I need to add organizationEIC property which ı use in the URL query to the response data's which are came as a result of my request. Let me make this clear with one example;
I am sending a request like **https://seffaflik.epias.com.tr/transparency/service/production/dpp-injection-unit-name?organizationEIC=40X000000000104H and as you can see it responses to me with 5 different plant data. I need to add the organizationEIC property -which ı use for get this 5- to this 5 response data and save like this to database to record which organization they are affiliated with. In another request with a different organizationEIC code, maybe it gets 2 plant data, so ı need to add my organizationEIC to this 2 plant data. So how can ı get this data from url to add my result datas in foreach loop?
I hope ı explained my problem clear and easy to understand. So here is my codes;
var datas = []
var result = []
var plantList = []
class App extends Component {
state = {
companies: [],
plants: []
}
componentDidMount() {
fetch('https://seffaflik.epias.com.tr/transparency/service/production/dpp-organization', {
method: "GET",
headers: {
"Content-Type": "application/json",
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response =>
response.json())
.then(async resultJson => {
this.setState({
companies: resultJson.body.organizations,
})
await this.getPlants(resultJson.body.organizations) //first get org. datas and send as param.
});
}
getPlants = async (items) => {
const data = await Promise.all(items.map((plant) => { //getting plants for each organization
return fetch(`https://seffaflik.epias.com.tr/transparency/service/production/dpp-injection-unit-name?organizationEIC=${plant.organizationETSOCode}`, {
method: 'GET',
headers: {
"Content-Type": "application/json",
'X-Requested-With': 'XMLHttpRequest'
}
}).then(response =>response.json()) //need some logic for my solution here probably :(
}))
data.forEach(element => {
datas.push(element.body.injectionUnitNames)
});
Array.prototype.push.apply(plantList, this.configure(datas))
this.setState({
plants: plantList
})
}
configure = (units) => {
units.forEach((unit) => {
unit.forEach((item) => {
result.push(item)
})
})
return result
}
I am open for any tips and tricks, thx in advance for your helps and advices :)
Add another then() to your fetch() and map the data with the new property
Something like:
const data = await Promise.all(items.map((plant) => { //getting plants for each organization
const {organizationETSOCode} =plant;
return fetch(`https://seffaflik.epias.com.tr/transparency/service/production/dpp-injection-unit-name?organizationEIC=${organizationETSOCode}`, {
method: 'GET',
headers: {
"Content-Type": "application/json",
'X-Requested-With': 'XMLHttpRequest'
}
}).then(response =>response.json())
.then(data=> data.map(o => ({...o, organizationETSOCode})))
}))

sending array data with multipart/form-data post request in Axios vue.js

I'm sending a post request from vue.js project using Axios and it contains a file upload, which requires me to use FormData, I found a nice answer that helped me with FormData:
const getFormData = object => Object.keys(object).reduce((formData, key) => {
formData.append(key, object[key]);
return formData;
}, new FormData());
and for the headers: headers: { 'Content-Type': 'multipart/form-data'}.
The POST call looks like this:
axios.post("http://127.0.0.1:8000/api/document/",
getFormData(this.documentData),
{
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
console.log("Successfully uploaded: ", response.data)
})
.catch(err => {
console.log("error occured: ", err)
})
This is the data I'm sending:
documentData: {
name: '',
file: '',
version: '',
company: '',
author: '',
category: []
}
When sending the data with single category id, it works fine, but when I send multiple category ids the following error shows:
"category": [
"Incorrect type. Expected pk value, received str."
]
How can I solve this problem?
Assuming your server-side process is expecting multiple, repeated field names for array types, you'll want something like this
const getFormData = object => Object.entries(object).reduce((fd, [ key, val ]) => {
if (Array.isArray(val)) {
val.forEach(v => fd.append(key, v))
} else {
fd.append(key, val)
}
return fd
}, new FormData());
Some server-side processes (PHP for example) require that collection-type fields include a [] suffix. If that's what you're working with, change this line
val.forEach(v => fd.append(`${key}[]`, v))
Also, when sending FormData from your browser, do not manually set the Content-type header. Your browser will do this for you, including the required boundary tokens
axios.post("http://127.0.0.1:8000/api/document/", getFormData(this.documentData))
.then(response => {
console.log("Successfully uploaded: ", response.data)
})
.catch(err => {
console.error("error occurred: ", err)
})
you can use json stringfy ,
I am using it also with vue app
formData.append("TeamMembers", JSON.stringify(this.TeamMembers));
axios
.post("/api/pro", formData, {
onUploadProgress: (progressEvent) => console.log(progressEvent.loaded),
headers: { "Content-Type": "multipart/form-data", }, })
Team members is an array .. and you can parse it in the other side this way
const myArr = ['bacon', 'lettuce', 'tomatoes'];
const myArrStr = JSON.stringify(myArr);
console.log(myArrStr);
// "["shark","fish","dolphin"]"
console.log(JSON.parse(myArrStr));
// ["shark","fish","dolphin"]
Object array passes values
var arr=['上海','北京'];
var formData = new FormData();
for (var i = 0; i < arr.length; i++) {
formData.append('city[]',arr[i]);
}

Passing in an array value into JSON format

I am creating an email app that sends messages to other people. Currently, I have it working except for the recipients column. Right now, I hard-coded an email into the recipients column to get it working. The reason is, is the recipients field is supposed to be an array.
What's the best way of passing a value from a user form (multiple addresses separated by commas) into JSON format?
Below is how I have it now.
Thanks!
const element = document.getElementById('sendEmail');
element.addEventListener('click', function() {
fetch('/emails', {
method: 'POST',
body: JSON.stringify({
recipients: 'card51short#gmail.com',
subject: document.querySelector('#compose-subject').value,
body: document.querySelector('#compose-body').value
})
})
.then(response => response.json())
.then(result => {
// Print result
console.log(result);
});
});
}
const element = document.getElementById('sendEmail');
element.addEventListener('click', function() {
const emailsFromForm = [ // NEW
document.querySelector('#email1').value, // NEW
document.querySelector('#email2').value // NEW
] // NEW
fetch('/emails', {
method: 'POST',
body: JSON.stringify({
recipients: emailsFromForm, // EDITED
subject: document.querySelector('#compose-subject').value,
body: document.querySelector('#compose-body').value
})
})
.then(response => response.json())
.then(result => {
// Print result
console.log(result);
});
});
}

Categories