How to update value in sessionStorage on method click? - javascript

In a React project, I have pay() method. A wallet balance is shown with certain coins. When pay() is clicked data is updated in purchase data. Coins data is stored in sessionStorage, but, after refresh of page data is missing.
Payment method
const onPayment = async (coins, _id) => {
try {
await fetch(`${config.baseUrl}customers/purchaseproduct?content_id=${_id}&coins=${coins}&v=1.0`, {
method:'POST',
headers: {
'Content-Type': 'application/json',
'ApiKey': config.apiKey,
'Authorization':sessionStorage.getItem('tokenNew'),
'platform':'web'
},
}).then((data) => data.json()).then((data2) => {
const balanceUpdated = data2.data.purchase.coins_after_txn
console.log('new balance', balanceUpdated) //new balance: 49990
{/* Here coins data is updated only on click of pay() method later on page refresh sessionStorage
value is empty */}
sessionStorage.setItem('walletData', balanceUpdated)
})
}
catch({error}) {
toast.error(error)
}
}
As you can see 'coins' are the price of product whereas '_id' is the id of specific product in onPayment method. walletData is updated only on payment and when refreshed the page, data is empty.
Take an example, A product price is $90 when clicked on pay() method $90 is cut from wallet 'balanceUpdated' and then passed on to sessionStorage in 'walletData' which is shown at that instance i.e 4900 but when page is refreshed 'walletData' is empty.
How to store the new updated value in sessionStorage and will remain it even after refresh?
LoginNow file
const onSubmit = async (data) => {
try {
let newData = await fetch('customers/auth/login', {
method:'POST',
headers: {
'Content-Type': 'application/json',
'ApiKey': config.apiKey,
'Platform': 'web',
},
body: JSON.stringify(data)
});
newData = await newData.json();
if(newData.error == true) {
toast.error(newData.error_messages[0])
} else {
const tokenData = newData.data.token
const walletData = newData.data.coinsxp.coins
sessionStorage.setItem('tokenNew', tokenData);
sessionStorage.setItem('walletData', walletData);
}
}
catch({error}) {
toast.error(error)
}
}

The data is probably there in the sessionStorage, you just have to retrieve it and write it in memory, on startup.
Probably you want something like this (or the other way around, depending on which value you want to have precedence):
const walletData = newData.data.coinsxp.coins || sessionStorage.getItem('walletData');
Putting data in sessionstorage is not equivalent to making it persistent. Putting data in sessionStorage means that it will just stay in session storage, it doesn't mean that your app data will be updated automatically based on it. This is why every time you call setItem, you should also call getItem - otherwise you are just stashing stuff somewhere, without accessing it.

Related

Axios Post inside loop with changing variable REACT

I have an array of labels for form inputs named changing_variable, which are dependent on what a user selects from a drop down menu, so these are unknown.
I need to be able to let the property of the Axios.post method, equal to the variable in order to input the correct data into my database.
Any examples I see online have properties like:
name: this.name
age: this.age
However this cannot work for me since I cannot hard code the values since they change depending on the user input, and also there is over a hundred for each user input.
If anyone can help me pass this changing variable to my backend. Thanks
My current code :
var i;
var changing_variable;
for(i=1; i<arr.length; i++)
{
changing_variable = inputValues[i].text
Axios.post(URL, changing_variable)
.then(res => {
console.log(res);
console.log(res.data);
console.log(changing_variable)
})
}
};
EDIT
Node.js code
app.post('/create', (req,res) => {
const test_variable= req.body.changing_variable;
db.query("INSERT INTO iptable (test_variable) VALUES(?)",
[test_variable], (err,result) =>{
if(err){
console.log(err)
}else {
res.send("Values Inserted")
}
}
)
});
Terminal error message
code: 'ER_BAD_NULL_ERROR',
errno: 1048,
sqlMessage: "Column 'test_variable' cannot be null",
sqlState: '23000',
index: 0,
sql: 'INSERT INTO iptable (test_variable) VALUES(NULL)'
The solution is Using application/x-www-form-urlencoded, URLSearchParams
By default, axios serializes JavaScript objects to JSON. To send data in the application/x-www-form-urlencoded format instead, you can use the URLSearchParams API.
const params = new URLSearchParams({ foo: 'bar' });
params.append('extraparam', 'value');
axios.post('/foo', params);
REF https://github.com/axios/axios#urlsearchparams

Django REST authentication not working with React

actually I want: if a user is authenticated: then create/get the Cart with user,
else: create/get the Cart with session key. But at first problem happened with authentication.
At first I tried to register the user and saved the key(got from drf) in local storage.
in Reactjs:
signupHandler=()=>{
fetch('http://127.0.0.1:8000/api/rest-auth/registration/', {
method: 'POST',
headers:{
'content-type':'application/json',
},
body:JSON.stringify({
'username':this.state.username,
'email': this.state.email,
'password1': this.state.pass1,
'password2': this.state.pass2
})
})
.then((response)=>{
response.json().then((result)=>{
if (result.key !== undefined){
localStorage.setItem('login', JSON.stringify({login: true,token:result.key}))
this.setState({registered: true})
}
})
})
}
I think no problem here. if I console.log() the key , it prints the key successfully.
now look at my views.py . I think the problem is here.
#api_view(['GET'])
##permission_classes((IsAuthenticated,))<<< if i comment out this line, and try to call this function, it shows >>>Forbidden: /addToCart/21/
def addToCart(request, pk):
print(request.user)#>>>AnonymousUser
product = get_object_or_404(Product, pk=pk)
if request.user.is_authenticated:
print('authenticated')#>>> nothing prints
mycart, __ = Cart.objects.get_or_create(user=request.user)
mycart.product.add(product)
else:
print('session')#>>>session
if not request.session.exists(request.session.session_key):
request.session.create()
mycart, __ = Cart.objects.get_or_create(session_key=request.session.session_key)
mycart.product.add(product)
return Response({'response':'ok'})
now i made a button and if i click, this function call
reactjs:
addToCart=()=>{
var id = this.props.id
let store = JSON.parse(localStorage.getItem('login'))
console.log(store.token);//successfully print the key
var url = 'http://127.0.0.1:8000/addToCart/'+id+'/'
fetch(url,{
method:'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token '+store.token
}
}).then(res=>res.json().then(result=>{
if(result.response === 'ok'){
this.props.dispatch({
type: 'itemInCart',
})
this.setState({addedToCart: true})
}
}))
}
So my question is:
*why it shows Forbidden if I comment out the line #permission_classes((IsAuthenticated,)) though i don't want this line. because I also want, user can add item with session.
*(in views.py) when i print request.user it shows >>>AnonymousUser. how to print the real user?
Finally, How can I add an item to the Cart with an Authenticated user?
You need to add either DEFAULT_AUTHENTICATION_CLASSES in settings.py or add a decorator #authentication_classes([TokenAuthentication]) to the api_view if not done already.
Since you need the API to also be accessible to unauthenticated users, #permission_classes is not required.

Change data in DOM after successful fetch PUT

I have an SPA in vanilla JS, using classes and modules.
The main idea is creating visits of customers and render them. When I fill in the form, data are sent to the server in JSON, after successful fetch, a visit card is created in the #content section.
The rendered card has two options: edit and delete. I made deletion without problems, I send DELETE, then just remove() the element onclick.
But I have some difficulties when editing the card.
I wrote the code to pop up modal form when click on the Edit button, and this form is filled with the card's data, so that the user can change them, click on Submit and send PUT to the server. The response is successful.
This is the edit form submit
edit(id) {
const readData = document.querySelector('.form-edit');
readData.addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Array.from(formData.entries()).reduce((memo, pair) => ({
...memo,
[pair[0]]: pair[1],
}), {});
editCard(data, id)
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong');
}
})
document.querySelector(".closeBtnEdit").click();
});
}
What I want, is to change the info of existing card in DOM after submitting the edited data.
This is the code of card rendering:
render(parent){
this.elem.fullName.textContent = this.fullName;
this.elem.purpose.textContent = `Purpose of the visit: ${this.purpose}`;
this.elem.desc.textContent = `Description: ${this.desc}`;
this.elem.priority.textContent = `Priority: ${this.priority}`;
this.elem.date.textContent = `Visit Date: ${this.date}`;
this.elem.delBtn.textContent = `Delete`;
this.elem.editBtn.textContent = `Edit`;
}
Edit card API:
function editCard(newCard, cardId) {
return fetch(`${API}/${cardId}`,{
method: "PUT",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newCard)
})
}

How to get access to Wix DB - Blog Posts

So right now I have a homepage, made by using html.
I want to add some divs, where I show the newest blogs I posted on my WIX page.
<div layout="row" layout-align="center center">
<md-card flex="60" class="pad-md md-body-1 border-1" md-colors="{"borderColor": "epprimary1-500", "color": "epsecondary6"}">
{{blog headline}}
Open Blog<md-icon>open_in_new</md-icon>
</md-card>
</div>
On the Wix platform, I know where they store the data in a so called dataset:
Now I need to know how to access these data from my other website.
I figured it out, finally!!
You can get the data you need via an http request.
Therefore, first of all, you need to add a javascript in your backend folder in Wix and name it "http-functions.js", delete it's content and add the folowing code.
Note: get_blogEntry() is method_functionName()
Blog/Posts is the DB I used, you can use any DB you have on wix.
import {ok, notFound, serverError} from 'wix-http-functions';
import wixData from 'wix-data';
export function get_blogEntry() {
let options = {
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
};
// query a collection to find matching items
return wixData.query("Blog/Posts")
.find()
.then( (results) => {
// matching items were found
if(results.items.length > 0) {
let itemOne = results.items[0];
let itemTwo = results.items[1];
options.body = {
"blogOneTitle": itemOne.title,
"blogOneUrl": "https://etaplus.energy" + itemOne.postPageUrl,
"blogTwoTitle": itemTwo.title,
"blogTwoUrl": "https://etaplus.energy" + itemTwo.postPageUrl
}
return ok(options);
}
})
// something went wrong
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
After you added this code in your backend, then you can access the data via the following URL:
"https://YOURWEBSITEURL/_functions/blogEntryor whatever your function name is"

React - How to set initial value of input element from redux?

Basic scenario -
I have an input element for e-mail address. On click of save, the e-mail is saved into the database. When I refresh, I want the saved value from database to show up as the initial value of the input. After that, I want to control the input's value through regular component state.
The problem I am having is setting the initial state value from props.
I thought I can set the state from props in CDU by making a prevProps to currentProps check.
Actual scenario -
The props I am trying to compare is an array of objects. So CDU shallow comparison won't help. How do I go about doing this?
Please note that I am not using or do not want to use any form library as I just have 3 input fields in my applications.
Thanks
You need to get data from the database on the component mount and set the state of your email. Like this below example (I am doing it on edit user) -
componentDidMount() {
var headers = {
"Content-Type": "application/json",
Authorization: `Token ${authToken}`
};
axios
.get(`${serverURL}users/${this.props.match.params.id}`, {
headers: headers
})
.then(res => {
//console.log(res.data);
let userdetails = res.data;
this.setState({
first_name: userdetails.first_name,
last_name: userdetails.last_name,
email: userdetails.email,
});
})
.catch(function(error) {
console.log(error);
});
}
Possible solution for this:
1. Create local state for email e.g
state = {
email: '';
}
dispatch the action in componentDidMount which will fetch the data and store it in redux state
use static getDerivedStateFromProps(props, state) to get updated values from props (ref. link :https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops) like
static getDerivedStateFromProps(nextProps, prevState) {
// do things with nextProps.email and prevState.email
return {
email: nextProps.someProp,
};
}

Categories