On a NodeJs project, I call my async function this way:
const response = await myFunction();
Here's the definition of the function:
myFunction = async () => {
return await new Promise((next, fail) => {
// ...
axios({
method: 'get',
url: apiEndpoint,
data: payload
}).then(function (response) {
// ...
next(orderId);
}).catch(function (error) {
fail(error);
});
});
}
How should I correctly intercept an error if that's happens? i.e. how I manage it when I await the function?
EDIT: as requested, a more complete snippet:
import express from 'express';
import { helpers } from '../helpers.js';
const router = express.Router();
router.post('/createOrder', helpers.restAuthorize, async (req, res) => {
// ...
const orderId = await api.createOrder();
let order = {
buyOrderId: orderId
}
const placed = await api.checkPlaced(orderId);
if (placed) {
let ack = await api.putAck(orderId);
order.checksum = placed.checksum;
order.ack = ack;
}
InternalOrder.create(order, (error, data) => {
if (error) {
return res.status(500).send({ message: error });
} else {
res.json("ok");
}
})
})
export { router as exchangeRouter }
Use try/catch:
let response;
try {
response = await myFunction();
} catch (error) {
// Handle error here.
}
Related
I'm getting github repo data, and then i store it in redis with set. with get am getting current data, but when i trying add function to get it's not working.
let redisClient;
(async () => {
redisClient = redis.createClient();
redisClient.on("error", (error) => console.error(`Error : ${error}`));
redisClient.on("connect", function () {
console.log("Redis Connected!");
});
await redisClient.connect();
})();
// Make request to Github for data
async function getRepos(req, res, next) {
try {
console.log("Fetching Data...");
const { username } = req.params;
// with this am getting result
const cacheResults = await redisClient.get(username);
console.log(cacheResults);
// with this am not getting result, how can i fix this?
redisClient.get(username, (err, data) => {
console.log(data);
});
const response = await fetch(`https://api.github.com/users/${username}`);
const data = await response.json();
const repos = data.public_repos;
// Set data to Redis
redisClient.set(username, JSON.stringify(repos));
res.send(setResponse(username, repos));
} catch (e) {
console.log(e);
res.status(500);
}
}
it's don't console.log(data), i searched a lot and everyone have one example how to use get function, but in me case it's don't log, whats am doing wrong?
this is my cache function
// Cache middleware
async function cache(req, res, next) {
const { username } = req.params;
try {
await redisClient.get(username).then((data) => {
if (data !== null) {
res.send(setResponse(username, data));
} else {
next();
}
});
} catch (error) {
console.log(error.toString());
}
}
app.get("/repos/:username", cache, getRepos);
it's works, but time finish times with cache and without it are same? am doing something wrong?
can you try like this
redisClient.get(username).then((data) => {
console.log(data);
});
i have a configuration with axios i am testing a feature to receive a list of students from an api, the problem is that it sends me an error:
TypeError:
constants_api_constants__WEBPACK_IMPORTED_MODULE_1_.default.interceptors.request
is not a function
For my axios configuration I use:
const options.GET_ALL_STUDENTS = {
method: "GET",
url: "/Student",
}
const BASE_API_URL = "https://localhost:7072/api";
const api = axios.create({
baseURL: `${BASE_API_URL}`,
});
const getStudents = () => {
return api.interceptors.request(options.GET_ALL_STUDENTS).use(
function request(success) {
return success;
},
function error(err) {
return err;
},
);
};
How I resolve my promise, (without interceptor this work fine):
function* fetchStudents() {
try {
const result1 = yield call(getStudents);
const studentList = createStudentListAdapter(result1.data);
yield put(fetchStudentsSuccess(studentList));
} catch (error) {
yield put(fetchStudentsFailure());
}
}
Interceptors are used to intercept any request/response before it goes to try/catch.
const getStudents = async () => {
try {
const res = await api(options.GET_ALL_STUDENTS);
// logic
} catch (e) {
// handle error
}
};
Interceptor
api.interceptors.request.use(
(request) => {
console.debug("Request", request.url);
return request;
},
(error) => {
console.debug("Request Failed", error.request.data.message);
return Promise.reject(error);
},
);
I have a form where i enter an email and it gets ''subscribed'' in a user.json file using a fetch api on node server.My task is to :
upon clicking on the "Unsubscribe" button, implement the functionality for unsubscribing from the community list. For that, make POST Ajax request using http://localhost:3000/unsubscribe endpoint.
I tried to make the function but it wasnt succeseful so i deleted it. Also,i need to do the following :
While the requests to http://localhost:3000/subscribe and
http://localhost:3000/unsubscribe endpoints are in progress, prevent
additional requests upon clicking on "Subscribe" and "Unsubscribe".
Also, disable them (use the disabled attribute) and style them using
opacity: 0.5.
For me ajax requests,fetch and javascript is something new,so i dont know really well how to do this task,if you could help me i'll be happy,thanks in advance.
fetch code for subscribing:
import { validateEmail } from './email-validator.js'
export const sendSubscribe = (emailInput) => {
const isValidEmail = validateEmail(emailInput)
if (isValidEmail === true) {
sendData(emailInput);
}
}
export const sendHttpRequest = (method, url, data) => {
return fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data ? {
'Content-Type': 'application/json'
} : {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!');
error.data = errResData;
throw error;
});
}
return response.json();
});
};
const sendData = (emailInput) => {
sendHttpRequest('POST', 'http://localhost:8080/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data);
window.alert(err.data.error)
});
}
index.js from route node server:
const express = require('express');
const router = express.Router();
const FileStorage = require('../services/FileStorage');
/* POST /subscribe */
router.post('/subscribe', async function (req, res) {
try {
if (!req.body || !req.body.email) {
return res.status(400).json({ error: "Wrong payload" });
}
if (req.body.email === 'forbidden#gmail.com') {
return res.status(422).json({ error: "Email is already in use" });
}
const data = {email: req.body.email};
await FileStorage.writeFile('user.json', data);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
/* GET /unsubscribe */
router.post('/unsubscribe ', async function (req, res) {
try {
await FileStorage.deleteFile('user.json');
await FileStorage.writeFile('user-analytics.json', []);
await FileStorage.writeFile('performance-analytics.json', []);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
module.exports = router;
And user.json file looks like this :
{"email":"Email#gmail.com"}
This is my attempt for unsubscribing :
export const unsubscribeUser = () => {
try {
const response = fetch('http://localhost:8080/unsubscribe', {
method: "POST"
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + error);
}
}
It gives the following errors:
Error: Error: Error with Status Code: undefined
main.js:2
main.js:2 POST http://localhost:8080/unsubscribe 404 (Not Found)
FileStorage.js:
const fs = require('fs');
const fsp = fs.promises;
class FileStorage {
static getRealPath(path) {
return `${global.appRoot}/storage/${path}`
}
static async checkFileExist(path, mode = fs.constants.F_OK) {
try {
await fsp.access(FileStorage.getRealPath(path), mode);
return true
} catch (e) {
return false
}
}
static async readFile(path) {
if (await FileStorage.checkFileExist(path)) {
return await fsp.readFile(FileStorage.getRealPath(path), 'utf-8');
} else {
throw new Error('File read error');
}
}
static async readJsonFile(path) {
const rawJson = await FileStorage.readFile(path);
try {
return JSON.parse(rawJson);
} catch (e) {
return {error: 'Non valid JSON in file content'};
}
}
static async writeFile(path, content) {
const preparedContent = typeof content !== 'string' && typeof content === 'object' ? JSON.stringify(content) : content;
return await fsp.writeFile(FileStorage.getRealPath(path), preparedContent);
}
static async deleteFile(path) {
if (!await FileStorage.checkFileExist(path, fs.constants.F_OK | fs.constants.W_OK)) {
return await fsp.unlink(FileStorage.getRealPath(path));
}
return true;
}
}
module.exports = FileStorage;
You should consider using a database for handling CRUD operations on your persisted data. If you must use filestorage, theres a flat file DB library called lowdb that can make working the files easier.
As for preventing duplicate requests, you can track if user has already made a request.
let fetchBtn = document.getElementById('fetch')
let isFetching = false
fetchBtn.addEventListener('click', handleClick)
async function handleClick(){
if (isFetching) return // do nothing if request already made
isFetching = true
disableBtn()
const response = await fetchMock()
isFetching = false
enableBtn()
}
function fetchMock(){
// const response = await fetch("https://example.com");
return new Promise(resolve => setTimeout (() => resolve('hello'), 2000))
}
function disableBtn(){
fetchBtn.setAttribute('disabled', 'disabled');
fetchBtn.style.opacity = "0.5"
}
function enableBtn(){
fetchBtn.removeAttribute('disabled');
fetchBtn.style.opacity = "1"
}
<button type="button" id="fetch">Fetch</button>
const express = require('express')
const router = express.Router()
const request = require('request')
const endponits = require('../sub/endpoints')
const status = require('../sub/status')
const db = require('../util/db')
const util = require('../util/util')
const CryptoJS = require('crypto-Js')
const fetch = require('node-fetch')
const notify = router.post('/', async (req, res) => {
console.log(req.body);
const CLIENT_SECRET = process.env.PAYMENT_TEST_SECRET_KEY;
// const amt = req.body.orderAmount;
let postData = {
oid: req.body.orderId,
amt: req.body.orderAmount,
rsn: req.body.txMsg,
tt: req.body.txTime
}
let signData =
req.body.orderId +
req.body.orderAmount +
req.body.referenceId +
req.body.txStatus +
req.body.paymentMode +
req.body.txMsg +
req.body.txTime;
// const postData = {
// oid: req.body.orderId,
// amt: req.body.orderAmount,
// refId: req.body.referenceId,
// sts: req.body.txStatus,
// pm: req.body.paymentMode,
// tm: req.body.txMsg,
// tt: req.body.txTime,
// signature: req.body.signature
// }
// var keys = Object.keys(postData);
// var signature = postData.signature;
// keys.sort();
// var signatureData = "";
// keys.forEach((key) => {
// if (key != "signature") {
// signatureData += postData[key];
// }
// });
// var computedSignature = crypto.createHmac('sha256', CLIENT_SECRET).update(signatureData).digest('base64');
// if (computedSignature == signature) {
let sdata = util.computeSign(signData);
if (sdata == req.body.signature) {
let data = {
sts: 'Inprogress',
//'so.pm': req.body.paymentMode || '',
//'so.refId': req.body.referenceId || '',
//uAt: Date.now()
}
db.getref(postData.oid, 'txn', successFunc => {
if (successFunc) {
const txnid = successFunc.id;
const appId = successFunc.appid;
db.updateById(
txnid,
data,
'txn',
success => {
if (success) {
let payload = {}
payload['txnId'] = txnid;
let PAYOUT_URI = 'https://ap.moneyorder.ws/api/v1/payout/test'
let Token = 'ceobrtoen'
let options = {
method: 'POST',
body: JSON.stringify(payload),
headers: {
appid: appId,
token: Token
}
}
try {
let response = await fetch(PAYOUT_URI, options)
let tokenres = await response.json()
//here we call payout Api
// let payload = { txnId: txnid };
// let Token = 'ceobrtoen';
// const PAYOUT_URI = 'https://ap.moneyorder.ws/api/v1/payout/test
// let options = {
// method: 'POST',
// url: PAYOUT_URI,
// body: JSON.stringify(payload),
// headers: {
// appid: appId,
// token: Token
// }
// }
// request(options, (err, response, body) => {
// if (err) {
// res
// .status(status.HTTPS.SERVER_ERROR)
// .json({ msg: 'Something went wrong.' })
// } else {
// let data = JSON.parse(body)
// console.log(data);
// console.log(options.body);
if (tokenres && tokenres.status === 'SUCCESS') {
// 3. update txn record
let updateObj = {
sts: 'Success',
}
db.updateById(
txnid,
updateObj,
'txn',
success => {
if (success) {
cosole.log("payout updated")
} else {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
},
err => {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
)
} else {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: "ERROR 1",
success: false
})
}
} catch (error) {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
// })
}
},
err => {
res
.status(status.HTTPS.BAD_REQUEST)
.json({ success: false, msg: 'error 404', data: null })
}
)
} else {
res
.status(status.HTTPS.BAD_REQUEST)
.json({ success: false, msg: "empty response" })
}
})
} else {
console.log(signData)
console.log(sdata)
}
})
module.exports = router
here I am using async and await but I am getting await only can be used inside an async function where I am wrong in this I am trying to hit other API but I am not getting success.i have also use request module instead of node-fetch but it is not working . can anybody tell me where I am wrong.......................................................................................................................................................
The success function of your db.updateById() isn't async, so you can't use await inside of it.
Also, consider abstracting those callback-style db functions, wrapping them in promises. That way, you can use async-await on the main flow of your application rather than nesting callbacks.
Please note you are doing an await inside success callback function of db.updateById()
Which should be async. Try this.
.
db.updateById( txnid,data, 'txn',
async (success) => {
},
async (err)=> {
}
}
if it dosent work and you can not make the success callback async for some reason
just return another function in the callback and make that async
db.updateById( txnid,data, 'txn',
success => {
(async () => {
})()
},
err => {
}
}
I am new to react native and making service call for the first time. My problem is service call is not going and getting warning like
Possible unhandled Promise Rejection, Reference error: response is not defined.
I am trying to hit loginUser function.
Api.js
const BASE_URL = "http://localhost:8200";
export const api = async (url, method, body = null, headers = {}) => {
try {
const endPoint = BASE_URL.concat(url);
const reqBody = body ? JSON.stringify(body) : null;
const fetchParams = {method, headers};
if((method === "POST" || method === "PUT") && !reqBody) {
throw new Error("Request body required");
}
if(reqBody) {
console.log("ReQBody--->"+reqBody);
fetchParams.headers["Content-type"] = "application/json";
fetchParams.body = reqBody;
}
const fetchPromise = await fetch(endPoint, fetchParams);
const timeOutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("Request Timeout");
}, 3000);
});
const response = await Promise.race([fetchPromise, timeOutPromise]);
return response;
} catch (e) {
return e;
}
}
export const fetchApi = async (url, method, body, statusCode, token = null, loader = false) => {
console.log("In FetchAPi Function");
try {
const headers = {}
const result = {
token: null,
success: false,
responseBody: null
};
if(token) {
headers["securityKey"] = token;
}
const response = await api(url, method, body, headers);
console.log("fetchApi-->>"+response);
if(response.status === statusCode) {
result.success = true;
let responseBody;
const responseText = await response.text();
try {
responseBody = JSON.parse(responseText);
} catch (e) {
responseBody = responseText;
}
result.responseBody = responseBody;
return result;
}
let errorBody;
const errorText = await response.text();
try {
errorBody = JSON.parse(errorText);
} catch (e) {
errorBody = errorText;
}
result.responseBody = errorBody;
console.log("FetchApi(Result)--->>"+result);
throw result;
} catch (error) {
return error;
}
}
auth.actions.js
export const loginUser = (payload) => {
console.log("In LoginUser function2");
return async (dispatch) => {
<-----**I am not able to enter into this block**------>
try {
dispatch({
type: "LOGIN_USER_LOADING"
});
console.log("In LoginUser function3");
const response = await fetchApi("/login", "POST", payload, 200);
if(response.success) {
dispatch({
type: "LOGIN_USER_SUCCESS",
});
dispatch({
type: "AUTH_USER_SUCCESS",
token: response.token
});
dispatch({
type: "GET_USER_SUCCESS",
payload: response.responseBody
});
return response;
} else {
throw response;
}
} catch (error) {
dispatch({
type: "LOGIN_USER_FAIL",
payload: error.responseBody
});
return error;
}
}
}
In console log, I can't see anything in network tab. In the android emulator, the mentioned warning has come.
My console tab
I see that your BASE_URL is served using an http endpoint. You can only make requests to https endpoints from react native projects. A possible workaround is to use ngrok. Just download it and run ./ngrok http 8200 since your port number is 8200. It will expose an HTTPS endpoint and replace your BASE_URL with that link and try fetching the data again.
I use the following code to make API calls. See if you can integrate it in your code. it is quite simple:
In a class called FetchService:
class FetchService {
adminAuth(cb, data) {
console.log('here in the fetch service');
return fetch(
baseURL + "login",
{
method: "POST",
headers: {
Accept: "application/json",
},
body: data
}
)
.then((response) => response.json())
.then(responsej => {
cb(null, responsej);
})
.catch(error => {
cb(error, null);
});
}
}
export default FetchService;
Then call it from your component using:
import FetchService from './FetchService';
const fetcher = new FetchService;
export default class LoginScreen extends React.Component {
fetchData() {
const data = new FormData();
data.append('username',this.state.username);
data.append('password',this.state.password);
fetcher.wastereport((err, responsej) => {
if(err) {
//handle error here
} else {
//handle response here
}
}, data);
}
}