How to update component in user collection Strapi v4 - javascript

[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;
}

Related

Firebase custom functions POST 3rd party API

i'm trying to create a custom function in Firebase custom functions to invoke a POST req to 3rd API. I was able to get together the syntax from frontend but I have no idea how to do it via firebase functions.
I need to rewrite this code - any help greatly appreciated
axios
.post(
URL,
{
order: {
category_id: 7,
status_id: 1,
aff_source_id: 1,
},
person: {
name: "n-a",
surname: "n-a",
phone: phone,
email: email,
},
extend: {
amount: maxMorgageBudget,
repayment_time: 30,
fixation: 5,
house_value: maxMorgageBudget * 1.1,
mortgage_purpose_id: mortPurpose,
income: income,
},
organization: 2,
},
{
headers: { "Content-Type": "application/json" },
auth: {
username: username,
password: password,
},
}
)
.then(async (response) => {
console.log(response.data);
})
.catch((error) => {
if (error.response) {
console.log(error.response.data); // => the response payload
}
});

React Router Adds URL Query Params on POST Request

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));
}

I am trying to store my data using react-redux, but it doesnt. How can I solve this?

I am working on a react project and when I try storing my data using postman, it works very well. But on the other hand, If i use react- redux, It doesn't get passed into the database. How can I resolve this? Here are some snippets of the code.
const mongoose = require('mongoose');
const verifySchema = new mongoose.Schema(
{
investment: {
type: mongoose.Schema.ObjectId,
ref: 'Investment',
},
topup: {
type: mongoose.Schema.ObjectId,
ref: 'TopUp',
},
verified: {
type: Boolean,
required: true,
},
verifiedBy: {
type: mongoose.Schema.ObjectId,
ref: 'Auth',
},
dateVerified: {
type: Date,
default: Date.now(),
required: true,
},
note: String,
createdAt: { type: Date, default: Date.now() },
paymentDates: [Date],
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
const Verify = mongoose.model('Verify', verifySchema);
module.exports = Verify;
This is the submit handler
const submitHandler = (e) => {
e.preventDefault();
if (isConfirmed === true) {
const paymentDates = [];
for (let i = 1; i <= investment.investmentDuration; i += 1) {
paymentDates.push(
moment(dateConfirm).add(i, 'months').add(1, 'days').toISOString()
);
}
const data = new FormData();
data.append('verified', isConfirmed);
data.append('investment', investment._id);
data.append('dateVerify', dateConfirm);
data.append('verifiedBy', userInfo.data.user._id);
data.append('amount', investment.investmentAmount);
data.append('duration', investment.investmentDuration);
data.append('paymentDates', paymentDates);
data.append('note', note);
dispatch(verifyInvestment(data));
}
};
This is the action
export const verifyInvestment = (formData) => async (dispatch, getState) => {
try {
dispatch({ type: VERIFY_CREATE_REQUEST });
const {
userLogin: { userInfo },
} = getState();
for (var pair of formData.entries()) {
console.log(pair[0] + ', ' + pair[1]);
}
const config = {
headers: {
// Authorization: `Bearer ${userInfo.token}`,
'Content-Type': 'application/json',
},
};
const { data } = await axios.post(`/api/v1/verify`, formData, config);
dispatch({
type: VERIFY_CREATE_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: VERIFY_CREATE_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
From My console, I get this message printed
verified, true
verifyActions.js:16 investment, 5fcde10d1ec7da05d54942ed
verifyActions.js:16 dateVerify, 2020-12-31
verifyActions.js:16 verifiedBy, 5fcc8739b926611a541a5baf
verifyActions.js:16 amount, 400000
verifyActions.js:16 duration, 12
verifyActions.js:16 paymentDates, 2021-01-31T23:00:00.000Z,2021-02-28T23:00:00.000Z,2021-03-31T23:00:00.000Z,2021-04-30T23:00:00.000Z,2021-05-31T23:00:00.000Z,2021-06-30T23:00:00.000Z,2021-07-31T23:00:00.000Z,2021-08-31T23:00:00.000Z,2021-09-30T23:00:00.000Z,2021-10-31T23:00:00.000Z,2021-11-30T23:00:00.000Z,2021-12-31T23:00:00.000Z
verifyActions.js:16 note, Hello World
POST http://localhost:3000/api/v1/verify 500 (Internal Server Error)
I get this message from the state.
verify(pin):"Verify validation failed: verified: Path verified is required."
Please I really do need help in resolving this.
If i try posting it using postman, It gets stored on the database but for this instance, it doesn't. I dont know if I have to empty some states before posting the data.
Did you try setting Content-Type header to "multipart/form-data". After all you are not posting JSON, you are posting FormData object.
If you are sending it from postman as json object, then you should do it in code too. But if you send it from postman as FormData then you should change the header.

React Stripe Payment Create Customer and Order / Shipping Address etc

I created stripe payment page using gatsby react and aws lambda. But this code not create customer data like ( shipping address, email etc. )
Lamdba Code
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
module.exports.handler = (event, context, callback) => {
console.log("creating charge...");
// Pull out the amount and id for the charge from the POST
console.log(event);
const requestData = JSON.parse(event.body);
console.log(requestData);
const amount = requestData.amount;
const token = requestData.token.id;
// Headers to prevent CORS issues
const headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type"
};
return stripe.charges
.create({
// Create Stripe charge with token
amount,
source: token,
currency: "usd",
description: "Tshirt"
})
.then(charge => {
// Success response
console.log(charge);
const response = {
headers,
statusCode: 200,
body: JSON.stringify({
message: `Charge processed!`,
charge
})
};
callback(null, response);
})
.catch(err => {
// Error response
console.log(err);
const response = {
headers,
statusCode: 500,
body: JSON.stringify({
error: err.message
})
};
callback(null, response);
});
};
Gatsby Payment Code
Code is working , payment is working. but shipping details not working.
openStripeCheckout(event) {
event.preventDefault();
this.setState({ disabled: true, buttonText: "WAITING..." });
this.stripeHandler.open({
name: "Demo Product",
amount: amount,
shippingAddress: true,
billingAddress: true,
description: "",
token: (token, args) => {
fetch(`AWS_LAMBDA_URL`, {
method: "POST",
body: JSON.stringify({
token,
args,
amount,
}),
headers: new Headers({
"Content-Type": "application/json",
}),
})
.then(res => {
console.log("Transaction processed successfully");
this.resetButton();
this.setState({ paymentMessage: "Payment Successful!" });
return res.json();
})
.catch(error => {
console.error("Error:", error);
this.setState({ paymentMessage: "Payment Failed" });
});
},
});
}
I want to see customer data , shipping address etc.
Thanks for helping.
The billing and shipping address are both available in the args-argument of the token callback you're collecting.
https://jsfiddle.net/qh7g9f8w/
var handler = StripeCheckout.configure({
key: 'pk_test_xxx',
locale: 'auto',
token: function(token, args) {
// Print the token response
$('#tokenResponse').html(JSON.stringify(token, null, '\t'));
// There will only be args returned if you include shipping address in your config
$('#argsResponse').html(JSON.stringify(args, null, '\t'));
}
});

React / Javascript Variables

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);
});
}

Categories