I'm using express and nodejs and have trouble with and then method logging a promise that stays pending.
edit().then(data => console.log(data));
Here is the edit function.
async function edit(data, id) {
let response = await fetch(config_url+'/subscriber/' + id, {
headers : { "content-type" : "application/json; charset=UTF-8"},
method: 'PUT',
body: JSON.stringify(data)
});
let ret = await repsonse.json();
return ret;
}
The rest api is express js.
Subscriber.edit = function (name, email, id, result) {
sql.query("UPDATE subscribers SET name=?, email=? WHERE id = ?", [name, email, id], function (err, res) {
if (err) {
console.log("error: ", err);
result(null, err);
} else {
console.log(res);
result(res);
}
});
};
The data changes in the database but below the res.send() line "subscriber changed successfully" in postman.
exports.edit_subscriber = function (req, res) {
console.log(req.params);
console.log(req);
console.log(res);
Subscriber.edit(req.body.name, req.body.email, req.params.id, function(err, subscriber) {
if (err) {
res.sendStatus(err);
}
res.send({ message: 'Subscriber succesfully edited'});
});
};
Again why does my own async function return a Promise that is not resolved and stays pending in the console of chrome.
EXPRESS ERROR
'access-control-allow-origin': [ 'Access-Control-Allow-Origin', '*' ]
}
}
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '(Rows matched: 1 Changed: 1 Warnings: 0',
protocol41: true,
changedRows: 1
}
/Users/[classified]/repos/[classified]]/node_modules/mysql/lib/protocol/Parser.js:437
throw err; // Rethrow non-MySQL errors
^
RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '(Rows matched: 1 Changed: 1 Warnings: 0',
protocol41: true,
changedRows: 1
}
at ServerResponse.writeHead (_http_server.js:241:11)
at ServerResponse._implicitHeader (_http_server.js:232:8)
at write_ (_http_outgoing.js:607:9)
at ServerResponse.end (_http_outgoing.js:717:5)
you have to stringify the res.send(JSON.stringify(json))
exports.edit_subscriber = function (req, res) {
...
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ message: 'Subscriber succesfully edited' }));
};
Also in the below code, you are passing the parameters to the callback incorrectly. The first parameter is err, second parameter is result. its not passed correctly.
Subscriber.edit = function (name, email, id, resultCallBack) {
sql.query("UPDATE subscribers SET name=?, email=? WHERE id = ?", [name, email, id], function (err, res) {
if (err) {
console.log("error: ", err);
resultCallBack(err);
} else {
console.log(res);
resultCallBack(null, res);
}
});
};
Also res.sendStatus accepts only status code.
res.sendStatus(400).send(JSON.stringify{message: 'error occured'});
hope this helps
you have typos and uneeded "let"
async function edit(data, id) {
let response = await fetch(config_url+'/subscriber/' + id, {
headers : { "content-type" : "application/json; charset=UTF-8"},
method: 'PUT',
body: JSON.stringify(data)
});
let ret = await repsonse.json();
return ret;
}
repsonse.json() won't work.
No need to let if you don't modify them later. Also, JSON.stringify might fail and you don't have any trycatch block.
async function edit(data, id) {
let serializedData = "";
try {
serializedData = JSON.stringify(data);
catch (error) {
// do something with error
}
const response = await fetch(config_url+'/subscriber/' + id, {
headers : { "content-type" : "application/json; charset=UTF-8"},
method: 'PUT',
body: serializedData
});
return response.json();
}
Related
I have a fetch request to delete some lists from my backend, but the console is giving me a complaint. The console says "Uncaught (in promise)."
This is my fetch() in the frontend:
const handleClickGarbage = (key) => { // for deleting a grocery list
const temp = loginUserr;
try {
console.log('inside click garbage');
const accessToken = temp.accessToken;
console.log(accessToken);
const param = key;
console.log(param);
fetch(`http://localhost:3010/v0/grocerylists?listName=${param}`, {
method: 'DELETE',
headers: new Headers({
'Authorization': 'Bearer ' + accessToken,
}),
})
.then((results) => {
if (!results.ok) {
throw results;
}
console.log(results);
getCurrentGroceryListTabInfo(); // get the current tab info again because we just updated the info
});
} catch (e) {
console.log(e);
}
};
This is my user.js:
exports.deleteGroceryList = async (req, res) => {
const listNamee = req.query.listName;
const memberIdd = req.userID;
console.log('inside delete gl');
console.log(listNamee);
console.log(memberIdd);
const deleted = await db.deleteGroceryList(listNamee, memberIdd);
console.log('user.js line 286)\n');
console.log(deleted);
if (deleted === null) {
res.status(400).send();
} else {
console.log('user.js line 292)\n');
res.sendStatus(200);
}
};
This is my db.js:
exports.deleteGroceryList = async (listNamee, memberIdd) => {
const listName = listNamee;
const memberId = memberIdd;
const select = 'DELETE FROM grocery_list WHERE list_name = $1 AND member_id = $2 RETURNING *';
const query = {
text: select,
values: [listName, memberId],
};
const {rows} = await pool.query(query);
console.log('db.js line 495)\n');
console.log(rows);
if (rows.length > 0) {
return rows.length;
} else {
return null;
}
};
And this is my openapi.yaml:
/grocerylists:
delete:
description: Deletes a grocery list from user's existing grocery lists'
security:
- bearerAuth: []
parameters:
- name: listName
in: query
description: name of grocery list to delete
schema:
type: string
responses:
200:
description: Removed list from grocery lists successfully
401:
description: Unauthorised
400:
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
I suspect it is something wrong with my api because console.logging results in the front end shows that user.js returned a status code of 200.:
But then the console also says uncaught promise:
You used .then() syntax to handle Promise. When you choose to use .then() syntax, you should catch the error with .catch(), and you don't have that in your code. Just add catch() method to a Promise that fetch returns.
fetch(`http://localhost:3010/v0/grocerylists?listName=${param}`, {
method: 'DELETE',
headers: new Headers({
'Authorization': 'Bearer ' + accessToken,
),
})
.then((results) => {
if (!results.ok) {
throw results;
}
console.log(results);
getCurrentGroceryListTabInfo(); // get the current tab info again because we just updated the info
})
.catch((error) => {
console.log('ERROR: ', error)
});
I would like both resolve() to return {valid_to: cert.valid_to, statusCode, statusMessage} and reject() should return {error: -1, statusCode, statusMessage}.
Question
How can I do that, when statusCode, statusMessage are in a different scope?
const https = require('https');
(async () => {
const options = {
hostname: "github.com",
port: 443,
path: '/',
method: 'GET',
timeout: 1000
};
options.agent = new https.Agent(options);
let valid_to = await new Promise((resolve, reject) => {
const req = https.request({
...options, checkServerIdentity: function (host, cert) {
resolve(cert.valid_to);
}
}).on('error', error => {
reject(-2);
});
req.on("timeout", chunk => {
reject(-1);
});
req.on('response', response => {
console.log(response.statusCode);
console.log(response.statusMessage);
});
req.end();
}).catch(error => {
console.log(error);
return -3;
});
})();
I will do something like this.
Edit: You need to specify res.on('data') in the https.request Object. Otherwise, timeout will always emit because there is no activity from the stream.
You can resolve in res.on("data") or res.on("end") and it is up to your use case.
res is an IncomingMessage object is created by http.ClientRequest and passed as the first argument to the 'request' and 'response' event respectively.
req is A reference to the original http.ClientRequest.
Both streams can emit events and you may handle them separately.
Also, when you reject the Promise, you actually cannot get the statusCode and StatusMessage from the req because there is an error in the req and the .on("response") will not be emitted. So, you need to customize the statusCode and statusMessage yourself.
const https = require("https");
// {valid_to: cert.valid_to, statusCode, statusMessage}
// {error: -1, statusCode, statusMessage}.
(async () => {
const options = {
hostname: "githubasdfa.com",
port: 443,
path: "/",
method: "GET",
timeout: 1000,
};
options.agent = new https.Agent(options);
try {
const response = await new Promise((resolve, reject) => {
let valid_to;
let statusCode;
let statusMessage;
const req = https
.request(
{
...options,
checkServerIdentity: function (host, cert) {
valid_to = cert.valid_to;
},
},
res => {
res.on("data", chunk => {
resolve({
valid_to,
statusCode,
statusMessage,
});
});
res.on("end", () => {
console.log("No more data in response.");
});
}
)
.on("error", err => {
console.log(err);
reject({
error: -2,
statusCode: "custom code",
statusMessage: "unhandled error",
});
})
.on("timeout", chunk => {
reject({
error: -1,
statusCode: "custom code",
statusMessage: "unhandled error",
});
})
.on("response", response => {
statusCode = response.statusCode;
statusMessage = response.statusMessage;
})
.end();
});
console.log(response);
} catch (error) {
console.log(error);
}
})();
I know this has been asked many times but what I am facing is a really annoying problem.
I have my server which returns error string with status code 500. When i use axios and catch the error, i can log it easily, but when i return it, i can try everything but its gives me undefined, or it doesn't append anything.
export const submitCheckout = async (betImport, ticket_id, token) => {
const res = await axios({
method: "post",
url: rootUrl + "bets/checkout/" + ticket_id,
headers: {
"x-auth-token": token,
},
data: {
betImport,
},
}).catch(({ response }) => {
console.log(response.status) //this works
return response;
});
return res.data;
};
//HERE I CALL THE FUNCTION
const res = await submitCheckout(sum, ticket_id, token);
//here i can access only the body of the error, even if i try to append something to it.
if (res.ticket_id) {
emptyTicket();
setmodal({
show: true,
title: "SUCCESS",
subtitle: "BET PLACED",
maxwin: `${res.maxWin}`,
ticketId: `${res.ticket_id}`,
account_sum: `${res.account_sum}`,
});
ModifyAccountUser(user, res.account_sum);
} else {
setmodal({
title: "ERROR",
show: true,
status: `${res.status}`,
error: `${res}`,
});
if (res.toString().includes("Token")) history.push("/login");
}
//WHAT I WANT TO DO
export const submitCheckout = async (betImport, ticket_id, token) => {
const res = await axios({
method: "post",
url: rootUrl + "bets/checkout/" + ticket_id,
headers: {
"x-auth-token": token,
},
data: {
betImport,
},
}).catch(({ response }) => {
return {...response, response.status}; //this returns the body only,
return {res: response, status: response.status}; //this crashes,
return response + "-"+ response.status}; //this was my desperation attack and failed as well
});
return res.data;
};
Throw an error and put your response inside it as a string. Then access it in your promise with error.message:
async function foo(){
try{
const res = await ax.post("url", {params})
return res
}
catch(err){
throw new Error("my error message")
}
}
//then
foo()
.then(res=> do stuff)
.catch(err=> err.message)
You can try this.
try {
let res = await Axios({
method: {method},
URL: {url},
data: {body}
});
let data = res.data;
return data;
} catch (error) {
console.log(error.response); // this is the main part. Use the response property from the error object
return error.response;
}
I am working on MERN Stack Application(Mean,Express,ReactJS,NodeJS). I have one issue is that I have many more methods in mlcontroller.js page and I call some methods on REST API so I call that methods under that API from mlrouter.js but all that API is Async so currently API takes data slots vise means I give u an example that in one time take 100 data from first method and then pass to another method and pass from all methods again come to first method and take next 100 data and repeat same process again but I need to take all data in one time means untill one method will not complete not move on another method how's that possible with node js?
I place my code here :
mlrouter.js
ensureApiAuthenticated,
authController.checkReadOnlyUser,
mlController.getAPIData,
mlController.getData,
mlController.getCRCDetails,
mlController.getDetails,
mlController.uploadData
)
MlController.js
async function getAPIData(req, res, next) {
try {
let loanboardapi = " ", dealersocket = " ";
loanboardapi = {
url: "https://loanboard.houstondirectauto.com/api/User/GetAuthorizationToken?username=amin#houstondirectauto.com&password=test#123",
method: "GET"
};
dealersocket = {
url: 'https://idms.dealersocket.com/api/authenticate/GetUserAuthorizationToken?username=ankur#houstondirectauto.com&password=H5d465#!ddfdd45dsfd688&InstitutionID=105815',
method: 'GET'
};
request(loanboardapi,
(err, res, body) => {
console.log("res = ", res);
console.log("body =", body);
loantoken = JSON.parse(body).token;
console.log(loantoken);
});
request(dealersocket,
(err, res, body) => {
console.log("res = ", res);
console.log("body =", body);
dealertoken = JSON.parse(body).Token;
console.log(dealertoken);
next();
});
}
catch (e) {
req.error = e;
next();
}
}
function getData(req, res, next) {
try {
let result;
request.get('https://idms.dealersocket.com/api/account/getaccountlist?token=' + dealertoken + '&LayoutID=2002313&PageNumber=1&accounttype=i&accountstatus=a,c,b,o,r,s,x',
(err, res, body) => {
console.log("res = ", res);
console.log("body =", body);
result = JSON.parse(body);
console.log(result);
totalpage = parseInt(result.TotalPages);
let resultdata = Object.assign({}, result.Data);
console.log(resultdata);
//getSSN(totalpage, dealertoken, next);
next();
})
}
catch (e) {
req.error = e;
next();
}
}
async function getCRCDetails(req,res,next) {
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 EMpInfoption = {
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 requestpromise(CBCOptions);
let EmployerInfoOptions = await requestpromise(EMpInfoption);
console.log(resultCBCOptions)
console.log(EmployerInfoOptions)
CRCOptions.push(resultCBCOptions);
EmpOption.push(EmployerInfoOptions);
} catch (error) {
console.log(error);
}
},
() => {
next();
}
);
}
async function getDetails(req,res,next) {
for(let i =0;i<CRCOptions.length;i++){
for(let j=0;j<EmpOption.length;j++){
let resdata = JSON.parse(CRCOptions[i]);
console.log(resdata);
result = resdata.data.DigifiResponse;
console.log(result);
let bodydata = JSON.parse(EmpOption[i]).data;
let crcssn = JSON.parse(CRCOptions[i]).ssn;
let empssn = JSON.parse(EmpOption[i]).ssn;
console.log("CRCSSN=",crcssn);
console.log("EMPSSN=",empssn);
if(crcssn == empssn)
{
for(let r=0;r<result.length;r++){
let crcdata = result[r];
console.log(crcdata);
for(let b=0;b<bodydata.length;b++) {
let annual_income;
console.log(bodydata[b]);
let mergedata = Object.assign(crcdata, bodydata[b]);
console.log("merge", mergedata);
if (mergedata["IncomeFrequency"] == "Monthly") {
annual_income = (parseInt(mergedata["Income"]) * 12).toString();
console.log(annual_income);
}
else {
annual_income = mergedata["Income"];
}
let binary = {
"accounts_opened": mergedata["total_number_of_open_accounts"],
"bankruptcies": mergedata["total_number_of_bankruptcies"],
"collections": mergedata["total_number_of_collections"],
"credit_inquiries_last_6_months": mergedata["total_number_of_inquires_in_the_last_6_months"],
"past_due_accounts": mergedata["total_number_of_accounts_currently_past_due"],
"open_accounts": mergedata["total_number_of_open_accounts"],
"high_credit_limit": mergedata["total_credit_limit_amount"],
"annual_income": annual_income
}
console.log(binary);
let arraybinary = Object.assign({},binary);
console.log(arraybinary);
binarydata.push(arraybinary);
console.log(binarydata);
let categorical = {
"bankruptcies_last_18_months": mergedata["count_of_bankruptcies_last_24_months"],
"credit_inquiries_last_6_months": mergedata["count_of_auto_loan_inquiries_last_9_months"],
"months_since_most_recent_inquiry": mergedata["total_number_of_inquires_in_the_last_6_months"],
"ninety_plus_delinquencies_last_18_months": mergedata["total_number_of_accounts_with_90180_day_delinquencies"],
"number_of_accounts_currently_30dpd": mergedata["total_number_of_accounts_with_3059_day_delinquencies"],
"open_credit_accounts": mergedata["total_number_of_open_auto_accounts"],
"pre_loan_debt_to_income": mergedata["total_amount_of_credit_debt"],
"total_current_balance": mergedata["total_account_balance"],
"total_high_credit_limit": mergedata["total_credit_limit_amount"],
"annual_income": annual_income
}
console.log(categorical);
let arraycategory = Object.assign({},categorical);
console.log(arraycategory);
categoricaldata.push(arraycategory);
let Linear = {
"bankruptcies_last_18_months": mergedata["count_of_bankruptcies_last_24_months"],
"credit_inquiries_last_6_months": mergedata["count_of_auto_loan_inquiries_last_9_months"],
"months_since_most_recent_inquiry": mergedata["total_number_of_inquires_in_the_last_6_months"],
"ninety_plus_delinquencies_last_18_months": mergedata["total_number_of_accounts_with_90180_day_delinquencies"],
"number_of_accounts_currently_30dpd": mergedata["total_number_of_accounts_with_3059_day_delinquencies"],
"open_credit_accounts": mergedata["total_number_of_open_auto_accounts"],
"pre_loan_debt_to_income": mergedata["total_amount_of_credit_debt"],
"total_current_balance": mergedata["total_account_balance"],
"total_high_credit_limit": mergedata["total_credit_limit_amount"],
"annual_income": annual_income
}
console.log(Linear);
let arraylinear = Object.assign({},Linear);
console.log(arraylinear);
Lineardata.push(arraylinear);
}
}
}
break;
}
}
console.log(binarydata.length);
console.log(binarydata);
converter.json2csv(binarydata,(err,csv) => {
if(err)throw err;
console.log(csv);
file.writeFileSync('/home/rita_gatistavam/Downloads/CSV/binarydata.csv',csv);
console.log('File Written');
})
converter.json2csv(Lineardata,(err,csv) => {
if(err)throw err;
console.log(csv);
file.writeFileSync('/home/rita_gatistavam/Downloads/CSV/lineardata.csv',csv);
console.log('File Written');
})
converter.json2csv(categoricaldata,(err,csv) => {
if(err)throw err;
console.log(csv);
file.writeFileSync('/home/rita_gatistavam/Downloads/CSV/categorydata.csv',csv);
console.log('File Written');
})
next();
}
async function uploadData(req,res,next){
let moduletype = sessionStorage.getItem('moduletype');
console.log(moduletype);
req.params.id = sessionStorage.getItem('modelid');
console.log(req.params.id);
try {
res.status(200).send({
status: 200,
timeout: 10000,
type: 'success',
text: 'Changes saved successfully!',
successProps: {
successCallback: 'func:window.createNotification',
},
responseCallback: 'func:this.props.reduxRouter.push',
pathname: `/ml/models/${req.params.id}/training/historical_data_${moduletype}`,
});
} catch (e) {
periodic.logger.warn(e.message);
res.status(500).send({ message: 'Error updating model type.', });
}
}```
Cannot understand your question, but I assume you want to get all the async request in one go.
You can achieve this with Promise.all, all the results will be returned as an array, and all the request will run at the same time.
const results = await Promise.all([asyncRequest1, asyncRequest2, asyncRequest3])
getting resulsts sequentially.
await asyncRequest1();
await asyncRequest2();
await asyncRequest3();
I have a promise within a selectRecipientData function that returns some user data from an api.
export async function selectRecipientData({ email }) {
engage.selectRecipientData({
listId: listId,
email: email,
returnContactLists: false,
}, function(err, result) {
if(err) {
console.log(err);
} else {
let recipient = JSON.stringify(result);
// this logs successfully
console.log('Recipient details: ' + recipient );
return recipient;
}
});
}
When I call this function within a post request. The data is logged within the promise but is undefined when returned as per below:
server.post('/api/v1/public/selectrecipientdata', async (req, res) => {
formData = req.body;
let { email } = formData;
if (!email) {
res.json({ error: 'Email is required' });
return;
}
try {
let recipientData = await selectRecipientData({ email });
// why is this undefined?
console.log('This is Undefined: '+ JSON.stringify(recipientData) );
res.json({recipientData});
} catch (err) {
res.json({ error: err.message || err.toString() });
}
});
Anyone tell me why? Thanks
You've written selectRecipientData as a callback style function, but you're calling it as an async/await style. If engage.selectRecipientData returns a promise, you could do something like:
export async function selectRecipientData({email}) {
const result=await engage.selectRecipientData({
listId: listId,
email: email,
returnContactLists: false,
});
const recipient=JSON.stringify(result);
console.log('Recipient details: ' + recipient );
return recipient;
}
Otherwise, to convert it to a promise you could do something like:
export function selectRecipientData({email}) {
return new Promise((resolve,reject)=>{
engage.selectRecipientData({
listId: listId,
email: email,
returnContactLists: false,
}, function(err, result) {
if (err) {
reject(err);
}
else {
let recipient = JSON.stringify(result);
console.log('Recipient details: ' + recipient);
resolve(recipient);
}
});
});
}