VueJS submit are delayed resulting in wrong data - javascript

I have a method in my Vue Instance which updates and removes a value from my database. When the method is submitted the values are updated correctly, but I need to do a refresh before the values are removed from the frontend. Below are my method:
async winBet(id, amount, bet) {
try {
this.bet.id = id
this.bet.amount = amount
this.bet.bet = bet
await this.$http.post("/user/winBet", this.bet);
} catch (err) {
console.log(err)
}
},
<form #submit="winBet(value._id, value.amount, value.bet)">
<button type="submit">Won</button>
</form>
I render the list, which after the submit should be not contain the submitted element, the following way
<ul v-for="value in pendingBets">
<li>Bet: {{value}}</li>
</ul>
________________________________________________________________
mounted() {
fetch('http://localhost:4000/user/getUser', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
'email': this.myval.email
}),
})
.then(function (response) {
return response.json();
}).then(function (data) {
this.pendingBets = data[0].allBets
}.bind(this));
}
For some reason I need to do a refresh before the value is removed from "pendingBets". Sometimes it works and sometimes I have to do the refresh. I'm still new to Vue so hope someone can ping me in the right direction here. Thank you in advance.

Re-hit the api as soon as you hit submit, I have defined a generic function called getData inside the methods which is being reused
methods: {
async winBet(id, amount, bet) {
try {
this.bet.id = id
this.bet.amount = amount
this.bet.bet = bet
await this.$http.post("/user/winBet", this.bet);
await this.getData();
} catch (err) {
console.log(err)
}
},
async getData() {
await fetch('http://localhost:4000/user/getUser', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
'email': this.myval.email
}),
})
.then(function (response) {
return response.json();
}).then(function (data) {
this.pendingBets = data[0].allBets
}.bind(this));
}
}
and your
mounted() {
this.getData();
}

The solution I came up with was to implement a window.location.reload() with a short setInterval.

Related

how to await value from another await variable

I cannot figure out how should I construct my code.
Basic info:
webhook (intercom) --> google cloud functions (await values) --> post message to slack.
Issue:
My code is working fine until I need to get an value from another await function and I am not sure how should I 'pause' the second await until the first one is complete.
Code:
// first function to get the information about agent
const getTeammateInfo = async function (teammate_id) {
try {
const response = await axios.get("https://api.intercom.io/admins/" + teammate_id, {
headers: {
'Authorization': "Bearer " + INTERCOM_API_AUTH_TOKEN,
'Content-type': "application/json",
'Accept': "application/json"
}
});
const { data } = response
return data
} catch (error) {
console.error(error);
}
};
// second function, which needs values from first function in order to find data
const slackID = async function (slack_email) {
if (slackID) {
try {
const response = await axios.get("https://api.intercom.io/admins/" + slack_email, {
headers: {
'Authorization': "Bearer " + SLACK_API_TOKEN,
'Content-type': "application/json",
'Accept': "application/json"
}
});
const { user } = response
return user
} catch (error) {
console.error(error);
}
}
};
It is used within the Google Cloud Function (
exports.execute = async (req, res) => {
try {
// map of req from intercom webhook
let {
data: {
item: {
conversation_rating: {
rating,
remark,
contact: {
id: customerId
},
teammate: {
id: teammateId
}
}
}
}
} = req.body
const teammateName = await getTeammateInfo(teammateId); // this works fine
const slackTeammateId = await slackID(teammateName.email) // this is where it fails I need to get the values from 'teammateName' in order for the function slackID to work
...
} catch (error) {
console.error(error)
res.status(500)
res.json({ error: error })
}
}
I have tried with Promise.all
const [teammateName, slackTeammateId] = await Promise.all([
getTeammateInfo(teammateId),
slackID(teammateName.email)
])
But I just cannot wrap my head around this how it should work.
Thank you.
// edit:
Code is okay, I just put the wrong API into the slackID function...
Thanks for double checking.
The problem with Promise.all() is that it fires both functions at the same time and waits until both are done, so you can't chain that way.
let teammateName
let slackTeammateId
getTeammateInfo(teammateId).then(r => {
teammateName = r
slackID(teammateName.email).then(r2 => {
slackTeammateId = r2
)}
);
then() method, on the other hand, waits until your method's return and then fires out everything in the callback function.

JSON.stringify() not working, but console.log() returns JSON

So I am making a request to an API endpoint. When I print JSONBody which is the variable data passed to POSTRequest(), I get the JSON I created printed to the log, however when I then try and JSON.Stringify() it, I get returned an empty object?
Was just wondering what I am doing wrong and how to fix it :)
getFileData()
const getFileData = () => {
var data = {}
// DO SOME STUFF HERE TO data
POSTRequest(data);
}
POSTRequest()
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
});
response.json()
.then(function (res) {
Promise.resolve(res)
.then(function (finalData) {
console.log(finalData);
props.setData(finalData);
});
});
} catch (error) {
console.log(error);
}
}
You're not waiting for the response from the fetch call correctly, try this:
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
}).then((response) => {
console.log(response);
props.setData(response);
}).catch((error) => {
console.log('POSTRequest error: ' + error)
})
});

Which one is executed first Fetch or setState?

I was trying to send data from frontend(React) to backend(express) from a HTML form, and clear the fields after submit. This is what it looks like. Here item and amount are state of controlled components. So my question is as I'm updating state before fetch its not updating it. As fetch and setState are async so which one will get executed first. Even if I write state updates after fetch then also it seems like fetch is executed first. But I'm not getting how ?
function onSub(e, setList, list) {
e.preventDefault();
setList([...list, { item, amount }]);
setItem("");
setAmt("");
fetch("http://localhost:3001/addData", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title: item, amt: amount }),
})
.then((res) => res.text())
.then((data) => {
console.log(data);
});
}
They're in a race. Normally you'd expect the state to get set first, since the state setters are operating just locally within the DOM and the fetch has to go talk to a server, but they're in a race and you can't count on which one is going to win the race.
If you want to control which happens first, you need to do that explicitly. It's easier to make the fetch finish first since you can just wait to call the state setters until the end of the fetch process. That also gives you the opportunity to handle a fetch failure (transient network error, for instance) without losing the information the user provided because you've already cleared it from state:
function onSub(e, setList, list) {
e.preventDefault();
fetch("http://localhost:3001/addData", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title: item, amt: amount }),
})
.then((res) => {
if (!res.ok) { // This check was missing
throw new Error(`HTTP error ${res.status}`);
}
return res.text();
})
.then((data) => {
console.log(data);
setList([...list, { item, amount }]);
setItem("");
setAmt("");
})
.catch(error => {
setError(/*...some error message saying something went wrong...*/);
});
}
Side note: I explain the comment about the check that was missing here. To avoid having to write all that boilerplate, I suggest having a few handy utility functions lying around, for instance:
export async function postJSON(url, data) {
const res = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
if (!res.ok) { // This check was missing
throw new Error(`HTTP error ${res.status}`);
}
return res;
}
Then the code would look like this:
function onSub(e, setList, list) {
e.preventDefault();
postJSON("http://localhost:3001/addData", { title: item, amt: amount })
.then((data) => {
console.log(data);
setList([...list, { item, amount }]);
setItem("");
setAmt("");
})
.catch(error => {
setError(/*...some error message saying something went wrong...*/);
});
}

Need to call Two APIs In Loop using node js

I have an array of ssn number and I have two api list in which I need to pass ssn number as request json so I need to call both api inside ssn loop so I pass ssn to json request during call both api but code is not work properly both api call at a time simulteniously, Where I need to call both api one by one.
Both API details and code are as follow
My Code:
let ssn = [460458524, 637625452, 453311896, 635285187, 455791630, 642348377, 463590491, 450730278, 641201851, 379965491];
async function getCRCDetails() {
ssn.forEach(function (item) {
if(item){
let CBCOptions = {
'method': 'POST',
'url': 'https://loanboard.houstondirectauto.com/api/Report',
'headers': {
'Content-Type': 'application/json',
'Cookie': 'ci_session=udmojmlc5tfl3epbrmtvgu6nao2f031p'
},
body: JSON.stringify({
"token": loantoken,
"action": "CBCReport",
"variables": {
ssn: item
}
})
}
request(CBCOptions, function (error, response) {
console.log(item);
console.log("CBCOPtion ", CBCOptions);
if (error) throw new Error(error);
result = (JSON.parse(response.body));
console.log("Result =", result);
CRCReport.push(result);
})
let EmployerInfoOptions = {
'method': 'POST',
'url': 'https://loanboard.houstondirectauto.com/api/Report',
'headers': {
'Content-Type': 'application/json',
'Cookie': 'ci_session=udmojmlc5tfl3epbrmtvgu6nao2f031p'
},
body: JSON.stringify({
"token": loantoken,
"action": "getEmployerInfo",
"variables": {
ssn: item
}
})
}
request(EmployerInfoOptions, function (error, response) {
console.log(response.body);
})
}
Here I need to call API request one by one.Anyone Guide me please.
I prefer use async await method for this situation
you need install and require async and request-promise
after that :
const request = require("request-promise");
const async = require("async");
let ssn = [460458524, 637625452, 453311896, 635285187, 455791630, 642348377, 463590491, 450730278, 641201851, 379965491];
async function getCRCDetails() {
//like a forEache
async.eachSeries(ssn, async (item) => {
let CBCOptions = {
method: "POST",
url: "https://loanboard.houstondirectauto.com/api/Report",
headers: {
"Content-Type": "application/json",
Cookie: "ci_session=udmojmlc5tfl3epbrmtvgu6nao2f031p",
},
body: JSON.stringify({
token: loantoken,
action: "CBCReport",
variables: {
ssn: item,
},
}),
};
let EmployerInfoOptions = {
method: "POST",
url: "https://loanboard.houstondirectauto.com/api/Report",
headers: {
"Content-Type": "application/json",
Cookie: "ci_session=udmojmlc5tfl3epbrmtvgu6nao2f031p",
},
body: JSON.stringify({
token: loantoken,
action: "getEmployerInfo",
variables: {
ssn: item,
},
}),
};
try {
let resultCBCOptions = await request(CBCOptions);
let EmployerInfoOptions = await request(EmployerInfoOptions);
console.log(resultCBCOptions)
console.log(EmployerInfoOptions)
//do pushing resultCBCOptions
//do pushing EmployerInfoOptions
} catch (error) {
console.log(error);
}
},
() => {
console.log("finished");
}
);
}
In Node the request methods that you are using are asynchronous. Meaning the runner (server) that runs the code does not wait for the request to finish and just continues to execute the next lines.
One thing that you can do is,
request.post(params).on("response", function(response) {
//....Do stuff with your data you recieve
// Make the next call here
request.post(params).on("response"), function() {
// Here you will have the second call's results
}
})
This ensures that both the API calls happen in order and only after the first one finishes.
Note:
The request library that you are using has been deprecated back in 2020. See https://github.com/request/request Hence, I would suggest you use other libraries like the standard https or http library that is shipped with node or you can use axios.
If you use a forEach loop without awaiting the results, you'll execute them all at the same time. Moreover, request library is kind of old and you need to convert its functions to return a promise.
Here's how I would do it.
const ssn = [1,2,3,4];
function download(item) {
return new Promise(function(resolve, reject) {
let options = {}; // construct your request
request(options, function (error, response) {
if(error) {
return reject(error);
}
resolve(response);
})
}
}
ssn = ssn.map(async function(item) {
let res = await download(item);
// process the result
return res;
});
You can also use the Bluebird library or get another client library such as got or axios.

Get response from axios with await/async

I'm trying to get JSON object from axios
'use strict'
async function getData() {
try {
var ip = location.host;
await axios({
url: http() + ip + '/getData',
method: 'POST',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
}).then(function (res) {
console.dir(res); // we are good here, the res has the JSON data
return res;
}).catch(function (err) {
console.error(err);
})
}
catch (err) {
console.error(err);
}
}
Now I need to fetch the res
let dataObj;
getData().then(function (result) {
console.dir(result); // Ooops, the result is undefined
dataObj = result;
});
The code is blocking and waits for the result, but I'm getting undefined instead of object
This seems to be one of those cases where async/await doesn't buy you much. You still need to return a result from the async function, which will return a promise to the caller. You can do that with something like:
async function getData() {
try {
let res = await axios({
url: 'https://jsonplaceholder.typicode.com/posts/1',
method: 'get',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
// Don't forget to return something
return res.data
}
catch (err) {
console.error(err);
}
}
getData()
.then(res => console.log(res))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
But in this example, since you don't need to do much in the actual function with the result, you're probably better off just returning axios's promise:
function getDataPromise() {
return axios({
url: 'https://jsonplaceholder.typicode.com/posts/1',
method: 'get',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
})
.then(res => res.data)
.catch (err => console.error(err))
}
getDataPromise()
.then(res => console.log(res))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
It is not what you would like to hear but
Async/Wait works on the principle "Whatever Happens in Vegas - Stays in Vegas". It means you could not pass benefits of using blocking IO calls outside of async block.
If you want to use async/await to create some kind of blocking IO call it would not work unless a block caller is also inside an async function what is not normally the case.
async/wait is only good if you want to have a long chain of IO calls but entire chain still MUST be non-blocking. Individual calls inside chain might be blocking but full chain not.
Example
async fn(url) { //this is a non blocking function
let res = await axios.get("http://jsonservice1"); //blocking but only inside this function
let res2 = await axios.get(url+'?s='+res.data);//res.data is resolved already
return res2; //this how it returns results but it will not be resolved until .then is called what is effectively a callback
}
fn("google.com").then(R=>console.log('sorry I am not blocking '+R.data));
Coming from ajax, I prefer modular approach. Data to be sent, function on success and function ‎on fail are separate from function using axios. Bellow sample code fetch user email against ‎user name form node.js and mysql at the backend. ‎
HTML: <button onclick=" testaxios();">TestAxios</button>‎
JS in browser:
var data = {
username: "myusername"
}
async function testaxios() {
try {
let res = await axios({
method: 'POST',
data: data,
url: '/testmysql',
});
if (res.status == 200) {
success(res);
};
}
catch (error) {
fail(error);
};
}
function success(res) {
console.log(res.data[0][0].email);
}
function fail(error) {
console.log(error);
}
JS in nodeJS at backend:
app.post("/testmysql", async function (req, res) {
try {
let usrname = req.body.username;
let em = await pool.query("SELECT email FROM users WHERE username = ?", usrname);
res.send(em);
} catch (err) {
console.log(err);
} });

Categories