I'm attempting to pass an Object from one Class to another which are in separate files. The overall goal is to consolidate my API calls into a single .js file for reference throughout the app.
The issue I'm having here is I'm unable to access the variables within the object within the .js file that calls the class.
Scenario:
I make my API calls in APICall.js and then attempt to pass the response data back to Page.js. I'm able to see my object in Page.js; however, I can't seem to access any of the variables to update my state.
Note: I'm new to ReactJS (and Javascript) with a solid Python background. Obviously these are two completely different beasts here.
Appreciate any assistance anyone can provide!
Console Logs Issues
:20 Object appears empty but shows values when extending.
:21 is a blank line but should be logging the first_name
:30 is a blank Object all together
--
TESTING !##
UpperNavigation.js:20 {first_name: "", last_name: "", email: "", company: ""}
company: "Testing 123"
email: "john#somewebsite.com"
first_name: "John"
last_name: "Doe"
__proto__: Object
UpperNavigation.js:21
UpperNavigation.js:30 {first_name: "", last_name: "", email: "", company: ""}
company: ""
email: ""
first_name: ""
last_name: ""
__proto__: Object
Page.js
state = {
first_name: '',
last_name: '',
email: '',
company: ''
}
componentWillMount() {
// this.getUserProfile.bind(this)
var userData = new vAPI().getUserProfile()
console.log("TESTING !##");
console.log(userData)
console.log(userData.first_name);
this.setState({
first_name: userData.first_name,
last_name: userData.last_name,
email: userData.email,
company: userData.company
});
console.log(this.state);
}
APICall.js
import axios from 'axios';
export default class vAPI {
constructor() {
this.state = {
first_name: "",
last_name: "",
email: "",
company: ""
}
}
getUserProfile(){
const URL = "https://somewebsite.com/api/user_profile/"
const USER_TOKEN = localStorage.getItem('access_token')
const AuthStr = 'JWT '.concat(USER_TOKEN);
axios.get(URL, { headers: { Authorization: AuthStr } }).then(response => {
this.state.first_name = response.data.first_name
this.state.last_name = response.data.last_name
this.state.email = response.data.email
this.state.company = response.data.company
}).catch((error) => {
console.log('error 3 ' + error);
});
return (this.state);
};
}
In getUserProfile() you are returning this.state before your axios get request is complete. When you call getUserProfile() from Page.js you are trying to access the data before it is set from your get request.
You should be returning the promise in getUserProfile() then using async/await or .then() when you call it in componentWillMount() before setting the data
getUserProfile(){
const URL = "https://somewebsite.com/api/user_profile/"
const USER_TOKEN = localStorage.getItem('access_token')
const AuthStr = 'JWT '.concat(USER_TOKEN);
return axios.get(URL, { headers: { Authorization: AuthStr } })
};
async/await
async componentWillMount() {
const userDataRes = await (new vAPI().getUserProfile());
const userData = userDataRes.data;
this.setState({
first_name: userData.first_name,
last_name: userData.last_name,
email: userData.email,
company: userData.company,
});
console.log('state', this.state);
}
promise
componentWillMount() {
new vAPI().getUserProfile().then((userDataRes) => {
const userData = userDataRes.data;
this.setState({
first_name: userData.first_name,
last_name: userData.last_name,
email: userData.email,
company: userData.company,
});
console.log('state', this.state);
});
}
Related
[details="System Information"]
Strapi Version: 4.5.5
Operating System: Windows
Database: MySQL
Node Version: 14.20
NPM Version: 8.18.0
Yarn Version: 1.22.19
[/details]
Hi there, I'm trying to updata a component called "billingAddress" within my user collection. I have set up a route to be able to enable a user to update their own data based on this video: Updating Your Own User Info in Strapi - YouTube
I'm able to update user data but once I need to update data in the component I'm not able to update any data.
This is what my extension looks like on the strapi backend:
module.exports = (plugin) => {
plugin.controllers.user.updateMe = async (ctx) => {
if (!ctx.state.user || !ctx.state.user.id) {
return ctx.response.status = 401;
}
await strapi.query('plugin::users-permissions.user').update({
where: { id: ctx.state.user.id },
data: ctx.request.body,
}).then((res) => {
ctx.response.status = 200;
})
}
plugin.routes['content-api'].routes.push(
{
method: "PUT",
path: "/user/me",
handler: "user.updateMe",
config: {
prefix: "",
policies: []
}
}
)
return plugin;
}
This is the Axios put request I'm using to update the user data from the frontend:
const handleUpdateBillingAddress = () => {
axios.put('http://localhost:1337/api/user/me', {
billingAddress: {
zipCode: "2840",
id: 1,
firstName: "Tim",
lastName: "kerrem",
company: "mycompany",
address1: "mystreet 42",
address2: null,
city: null,
country: "Belgium",
provinceOrState: null,
zipCode: null,
phone: "+31412412412",
email: null
}
},
{
headers: {
'authorization': `Bearer ${jwt}`,
'Content-Type': 'application/json'
},
},
)
.then(response => {
console.log(response)
notification.open({
type: 'success',
message: 'Success!',
description:'Your user information has been updated',
});
})
.catch(error => {
console.log(error);
console.log('An error occurred:', error.response);
notification.open({
type: 'error',
message: 'Something went wrong',
description:'Some of your credentials are not valid',
});
});
}
Would be really helpful if someone could advise me on how to update the component
Hi you wanna try doing this via entityService strapi doc's states:
The Entity Service API is the recommended API to interact with your application's database. The Entity Service is the layer that handles Strapi's complex data structures like components and dynamic zones, which the lower-level layers are not aware of.
reference
so try:
await strapi.entityService.update('plugin::users-permissions.user', ctx.state.user.id, {data: ctx.request.body })
By using entityService and doing some tweaking with data and populate parameters I was able to get this working with following code:
module.exports = (plugin) => {
plugin.controllers.user.updateMe = async (ctx) => {
if (!ctx.state.user || !ctx.state.user.id) {
return ctx.response.status = 401;
}
const billingData = ctx.request.body.billingAddress;
await strapi.entityService.update('plugin::users-permissions.user', ctx.state.user.id, {
data: {
billingAddress: {
firstName: billingData.firstName,
lastName: billingData.lastName,
company: billingData.company,
address1: billingData.address1,
city: billingData.city,
country: billingData.country,
provinceOrState: billingData.provinceOrState,
zipCode: billingData.zipCode,
phone: billingData.phone,
email: billingData.email,
},
},
populate: ["billingAddress"],
}).then((res) => {
ctx.response.status = 200;
})
}
plugin.routes['content-api'].routes.push(
{
method: "PUT",
path: "/user/me",
handler: "user.updateMe",
config: {
prefix: "",
policies: []
}
}
)
return plugin;
}
console error ->
[1]: https://i.stack.imgur.com/xOfUV.png
axios
.post("https://bootcamp-2022.devtest.ge/api/application", {
token: "7e475dfc-0daa-4108-81c8-d6c62a3df4ca",
first_name: JSON.parse(localStorage.getItem("PersonalInfo").first_name),
last_name: JSON.parse(localStorage.getItem("PersonalInfo").last_name),
email: JSON.parse(localStorage.getItem("PersonalInfo").email),
skills: JSON.parse(localStorage.getItem("techskill").skills),
work_preference: JSON.parse(
localStorage.getItem("covid").work_preference),
.then((res) => console.log(res))
.catch((err) => {
console.log(err);
As the error metioned you have an error on your json
This is your current code
first_name: JSON.parse(localStorage.getItem("PersonalInfo").first_name)
This is how it should be
first_name: JSON.parse(localStorage.getItem("PersonalInfo")).first_name
And you might want to hide the api and the token .
I am unable to extract the name variable from the graph output of the following react code. trying to store the name value from the json output received from the api in my state variable in React. How do i do it?
state = {
auth: false,
username: '',
access_token: '',
app_name: [],
};
responseFacebook = response => {
{/*console.log(response);*/}
if(response.status !== 'unknown')
this.setState({
auth: true,
username: response.name,
access_token: response.accessToken
});
graph.setAccessToken(this.state.access_token);
graph.get("/me/accounts", function(err, res) {
let response = res;
console.log(response.data[0]);
});
console.log(this.state);
}
Maybe because your checking the second console.log outside the callback. In javascript the callbacks( the function inside the get call ) are trigerred later, when the API completes, hence you will not get anything in the console.log outside the callback, if you rewrite your example it might work.
state = {
auth: false,
username: '',
access_token: '',
app_name: [],
};
responseFacebook = response => {
if(response.status !== 'unknown') {
this.setState({
auth: true,
username: response.name,
access_token: response.accessToken
});
graph.setAccessToken(this.state.access_token);
graph.get("/me/accounts", (err, res) => {
let response = res;
this.setState({username:response.data[0]});
console.log(this.state);
});
}
}
Event loop reference
Hello my fellow nerds,
I am running into an issue where when I make a POST request (using Axios library inside of React function), it automatically appends all of the data from the "Create a User" form into search parameters in the URL of the page upon submission. I don't like this because I'd rather this stay hidden within the POST request, not flung out onto the page URL.
Image: URL after user was created
This is a direct result of React Router adding the data sent in the request of the body being appended to the location.search of react router's history object. So, naturally, since the react router history object is mutable, I tried adding this to the response of the submission:
this.props.location.search.replace({*some random parameter stuff here*});
This was in hopes it would remove all of that stuff from the URL and redirect to the page without search parameters. Anyways, I have seen a few other posts similar in nature but they don't seem to answer this exact question.
TL;DR: I am trying to send a POST request without React Router adding my req.body data to the params in my URL and the location.search object.
MY CODE:
Users.js: (front end)
handleSubmit (e) {
Axios.post(`${server}/s/admin/users/create`, {
headers: {
'Content-Type': 'application/json'
},
data: {
firstName: this.state.firstName,
lastName: this.state.lastName,
username: this.state.username,
password: this.state.password,
email: this.state.email
}
}).then((res) => {
console.log(res);
}).catch(err => console.log(err));
}
users.js: (back end)
app.post("/s/admin/users/create", (req, res) => {
let rb = req.body.data;
let newUser = new User({
_id: uid.time(),
orgID: req.session.orgID,
email: rb.email,
username: rb.username,
password: bcrypt.hashSync(rb.password, hashRate),
firstName: rb.firstName,
lastName: rb.lastName,
data: { exist: "true" },
settings: { exist: "true" }
});
// Save new owner to db
newUser.save((err, data) => {
if (err) return console.error(err);
res.json({info: `A new user, ${newUser.firstName} ${newUser.lastName}, has been created successfully.`});
});
});
Thank you!
P.S. This is my first post, thank you for your patience. I've tried searching and solving this issue for about a day now.
Can you try rewriting it this way? cause axios.post expect
axios({
method: 'post',
url: `${server}/s/admin/users/create`,
headers: {
'Content-Type': 'application/json'
},
data: {
firstName: this.state.firstName,
lastName: this.state.lastName,
username: this.state.username,
password: this.state.password,
email: this.state.email
}
}).then((res) => {
console.log(res);
}).catch(err => console.log(err));
Axios.post method expect the second argument as data but you have passed config, another way is to pass data and config in the third argument.
handleSubmit(e) {
Axios.post(`${server}/s/admin/users/create`, {
firstName: this.state.firstName,
lastName: this.state.lastName,
username: this.state.username,
password: this.state.password,
email: this.state.email
}, {
headers: {
'Content-Type': 'application/json'
}
}
}).then((res) => {
console.log(res);
}).catch(err => console.log(err));
}
Here is my snippet:
import axios from 'axios';
import FormData from 'form-data';
var fs = require('fs');
submitCareerForm(e){
e.preventDefault();
let formData = new FormData(); //formdata object
formData.append('first_name',this.state.fname);
formData.append('last_name',this.state.lname);
formData.append('cv', fs.createReadStream(this.state.cv));
formData.append('email', this.state.email);
formData.append('phone',this.state.phone);
formData.append('details',this.state.details);
formData.append('preferred_contact',this.state.preferredContact);
console.log('resume ****** ',this.state.cv)
let config = {
method: 'post',
url: 'https://sbtsbackend.azurewebsites.net/users/carrers',
data : formData
};
axios(config)
.then(resData => {
console.log('result data ******** ',resData)
if(resData.data.statusCode == 200){
alert(resData.data.message);
}
this.setState({
fname: '',
lname: '',
cv: '',
address: '',
city: '',
state: '',
postalcode: '',
country: '',
phone: '',
email: '',
details: '',
});
})
.catch((error)=>{
console.log('error ******* ',error)
})
}
I want to upload document type doc, docx or pdf. On postman the api is working fine. How can I implement here?
This is the error I am getting:
The fs module for Node.js is only available for server side applications. When you use it in a web browser for client side applications, it will throw an error.