I have problem with my node.js helper. My helper send post request to payu API, API return access_token which i need. If receive access_token then i need return him.
My code:
module.exports = {
createPaymentToken: async () => {
const response = await request({
method: 'POST',
json: false,
url: payuAuthUrl,
form: {
'grant_type': 'client_credentials',
'client_id': payuMerchantID,
'client_secret': payuSecret,
}
},
function (error, response, body) {
if (response) {
const result = (JSON.parse(body));
const token = result.access_token;
return token;
}
}
);
},
When i add console.log(token) before return token, then i see my access_token. The problem is when I want to pass this token to the controller, i.e. it reaches me undefined.
My controller
testPayment: async (req, res) => {
var result = await payuHelper.createPaymentToken();
res.send({
result
});
},
I have no idea what I'm doing wrong.
Your return statement was placed inside callback, so the createPaymentToken function doesn't return anything, just fix your code like sample below:
module.exports = {
createPaymentToken: () => {
return new Promise((resolve, reject) => {
request({
method: 'POST',
json: false,
url: payuAuthUrl,
form: {
'grant_type': 'client_credentials',
'client_id': payuMerchantID,
'client_secret': payuSecret,
}
},
function (error, response, body) {
if (error) {
return reject(error)
}
if (response) {
const result = (JSON.parse(body));
const token = result.access_token;
return resolve(token);
}
}
);
})
},
}
Promise document
Related
function getToken()
{
return axios.request({
url: "/xyz",
method: "post",strong text
baseURL: "https://api.testing.in/api/xyz",
data: {
"ClientKey" : "xyz",
"ClientSecret" : "xyz"
}
}).then(response => {
// tokeniw=response.data.accessToken
// console.log('Check data inside then :' + tokeniw)
// return tokeniw;
this.response = response.data
return response.data.accessToken
})
}
Here , i want to put response.data.accessToken into a variable outside this function
I would rewrite the code and call it as:
function getToken() {
return new Promise((resolve, reject) => {
axios.request({
url: "/xyz",
method: "post",
baseURL: "https://api.testing.in/api/xyz",
data: {
"ClientKey": "xyz",
"ClientSecret": "xyz"
}
})
.then(response => resolve(response.data.accessToken))
.catch(e => reject(e))
})
}
const token = await getToken();
Hi I made a module and when I try to return the song name it is just undefined, the console.log just before it works though so I'm a little confused. The line after console.log(`"${songName}" by ${artistsList}`) is where the issue is, I try to return "${songName}" by ${artistsList} but the return is just undefined so I am a little stuck on why
Code: (This is the spotify.js module)
I call it with const Spotify = require("./spotify.js"), everything works up until I need to just return the song name using the Spotify.request() function
const axios = require("axios");
module.exports = {
token: "",
ref: "",
refresh: function () {
axios({
method: "post", //you can set what request you want to be
url: "https://accounts.spotify.com/api/token",
data:
`grant_type=refresh_token&refresh_token=${this.ref}`,
headers: {
Authorization:
"Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(response => {
this.token = response.data.access_token
console.log(`Successfully refreshed token ${module.exports.token}`);
});
},
analyseSong: function (data) {
console.log(data)
const x = data;
//console.log(x)
if (x.is_playing) {
const songNameMatch = x.item.name.split("(");
var songName = x.item.name;
try {
const letter = songNameMatch[1].charAt(0);
letter.toLowerCase() == "f" ||
songNameMatch[1].toLowerCase().match(/^with/)
? (songName = songNameMatch[0].trim())
: false;
} catch (err) {
false;
}
var artistArray = [];
var artist;
const artists = x.item.artists;
//console.log(token)
for (artist in artists) {
artistArray.push(x.item.artists[artist].name);
}
//console.log(artistArray)
const artistsList = artistArray.join(", ");
//console.log(artistsList)
//console.log(`Currently playing: ${songName} - ${artistsList}`);
console.log(`"${songName}" by ${artistsList}`)
return `"${songName}" by ${artistsList}`;
} else {
return `Not currently listening to a song`;
}
},
request: function () {
axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
module.exports.analyseSong(response.data);
})
},
}
So I'm doing X=Spotify.request() trying to get the song name as X so I can output using IRC chat
There are a couple problems. .request() has no return value at all. So, it will never return anything other than undefined. You can fix that like this by adding two return statements, the first to return the promise itself and the second to make the return value from analyseSong() be the resolved value of that promise:
request: function () {
return axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
return module.exports.analyseSong(response.data);
})
},
Now Spotify.request() will return a promise that will resolve with the value returned from .analyseSong(response.data). You would use that promise like this:
Spotify.request().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
the code below is the first request for get list data
mounted() {
this.getList()
},
methods: {
handleClick(row) {
console.log(row.id)
console.log(row.url)
this.$router.push({ name: 'Main', query: { id: row.id } })
},
getList() {
axios
.get('/api/v1/requests/all', {
params: {
userId: this.$store.state.userInfo.id,
},
})
.then(response => {
let moment = require('moment')
for (var item of response.data.data) {
item.createdAt = moment(item.createdAt).format(
'YYYY-MM-DD HH:mm:ss',
)
}
this.items = response.data.data
})
.catch(error => {
console.log(error)
})
}
my interceptor
axios.interceptors.response.use(
function (response) {
return response
},
async function (error) {
const originalRequest = error.config
if (error.response.status === 401 && !originalRequest._retry) {
error.response.config._retry = true
sessionStorage.removeItem('access-token')
let headers = {
grant_type: 'refresh_token',
Authorization: sessionStorage.getItem('refresh-token'),
}
axios
.post('/api/v1/users/refresh_token', {}, { headers: headers })
.then(response => {
let token = response.data.data
sessionStorage.setItem('access-token', token)
originalRequest.headers['Authorization'] = token
originalRequest.headers['grant_type'] = 'grant_type'
return axios.request(originalRequest)
})
.catch(error => {
console.log(error)
alert('blablabla.')
})
}
return Promise.reject(error)
},
)
the flow is i understand
1.token expired
2.move to list page
3.mounted hook is request data
4.getList -> axios get('~~request/all')
5.interceptor->axios post('~~~refresh_token')
6.re request with new token(request/all)
7.re request is 200, but not update list page
i'd really appreciate your help :)
Seems like you need to return the second request (await for result and return). Right now the result of second request seems to be ignored
axios.interceptors.response.use(
function (response) {
return response;
},
async function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
error.response.config._retry = true;
sessionStorage.removeItem("access-token");
let headers = {
grant_type: "refresh_token",
Authorization: sessionStorage.getItem("refresh-token"),
};
const [secondError, res] = await axios // await here
.post("/api/v1/users/refresh_token", {}, { headers: headers })
.then(async (response) => {
let token = response.data.data;
sessionStorage.setItem("access-token", token);
originalRequest.headers["Authorization"] = token;
originalRequest.headers["grant_type"] = "grant_type";
return [null, await axios.request(originalRequest)];
})
.catch((err) => {
console.log(err);
alert("blablabla.");
return [err, null];
});
// Handle here
if(secondError) {
return Promise.reject(secondError);
}
return Promise.resolve(res)
}
return Promise.reject(error);
}
);
The above solution worked for me perfectly. here's the modified code that I used for my requirement.
export default function axiosInterceptor() {
//Add a response interceptor
axios.interceptors.response.use(
(res) => {
// Add configurations here
return res;
},
async function (error) {
const originalRequest = error.config;
let secondError, res
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
[secondError, res] = await axios({
method: "POST",
url: `${baseURL}/account/token/refreshtoken`,
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
.then(async (response) => {
//handle success
return [null, await axios.request(originalRequest)];
}).catch(function (error) {
console.error(error)
});
}
if (secondError) {
return Promise.reject(secondError);
}
return Promise.resolve(res)
}
);
}
Actually i am using ajax call to connect to a 3rd party api when i am using the api on browser and i am able to get the data from the api.
Here is the AJAX code:-
var settings = {
async: true,
//crossDomain: true,
url: "https://rest.cricketapi.com/rest/v2/schedule/?access_token=XXX"
//"url": "https://rest.cricketapi.com/rest/v2/match/indaus_2020_one-day_02/?access_token=XXX"
//bblt20_2019_g28
};
//create token for the api for 24hours
let token;
function getToken() {
$.ajax({
type: "POST",
url: "https://rest.cricketapi.com/rest/v2/auth/",
data: {
access_key: "********************************",
secret_key: "********************************",
app_id: "http://localhost:8000/",
device_id: "developer"
},
success: function(data) {
console.log(data);
token = data.auth.access_token;
console.log(token,);
//do something when request is successfull
createUpcomingMatchesSchedule();
},
dataType: "json"
});
}
function createUpcomingMatchesSchedule() {
var urlJson = settings.url;
urlJson = urlJson.replace(/XXX/g, token);
settings.url = urlJson;
$.ajax(settings).done(function(response) {
console.log(response);
toGetUpcomingMatches(response);
});
}
Now i want to convert this ajax method into http request so that i can use the data on the server using nodejs.
Here is the code:-
const { db } = require("../../utility/admin");
var request = require("request");
// //*************************** API INITIALIZATION ********************************
var settings = {
async: true,
//crossDomain: true,
url: "https://rest.cricketapi.com/rest/v2/schedule/?access_token=XXX"
//"url": "https://rest.cricketapi.com/rest/v2/match/indaus_2020_one-day_02/?access_token=XXX"
//bblt20_2019_g28
};
var options = {
method: "POST",
// hostname: "https://rest.cricketapi.com",
uri: "https://rest.cricketapi.com/rest/v2/auth/",
access_key: "********************************",
secret_key: "********************************",
app_id: "http://localhost:8000/",
device_id: "developer"
};
let token;
function getToken() {
request(options, function(error, response, body) {
if (error) {
console.log(error);
} else {
console.log(body);
token = body.auth.access_token;
console.log(token);
// console.log(response);
}
});
}
module.exports = { getToken };
But i am not able to access the data from the api when i am using the nodejs code.
Thanks in advance
👨🏫 For an example, you can look at this code below: 👇
var options = {
method: "POST",
// hostname: "https://rest.cricketapi.com",
uri: "https://rest.cricketapi.com/rest/v2/auth/",
// make sure, on this API, use body or headers.
// If body, you can change this `headers` to `form`.
headers: {
access_key: "********************************",
secret_key: "********************************",
app_id: "http://localhost:8000/",
device_id: "developer"
}
};
let token;
function getToken() {
return new Promise((resolve, reject) => {
request(options, function(error, response, body) {
if (error) return reject(error)
body = JSON.parse(body);
console.log(body);
token = body.auth.access_token;
return resolve(token);
});
})
}
I hope it can help you 🙏.
This question already has answers here:
How do I wait for a promise to finish before returning the variable of a function?
(4 answers)
Closed 4 years ago.
When I try to call this oauth-1.0 API request,
const request = require('request');
const OAuth = require('oauth-1.0a');
const crypto = require('crypto');
function main(params) {
// Dependencies
// Initialize
const oauth = OAuth({
consumer: {
key: '****',
secret: '****'
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});
// Note: The token is optional for some requests
const token = {
key: '****',
secret: '****'
};
const request_data = {
url: 'http://****/rest/V1/products/12345',
method: 'GET',
//data: { status: 'Hello Ladies + Gentlemen, a signed OAuth request!' }
};
return new Promise((resolve, reject) => {
request({
url: request_data.url,
method: request_data.method,
form: request_data.data,
headers: oauth.toHeader(oauth.authorize(request_data, token))
}, function (err, res, body) {
//console.log(res.body.name);
if (err){
reject({
statusCode: 500,
headers: { 'Content-Type': 'application/json' },
body: {'message': 'Error processing your request' },
});
} else {
resolve({
body: JSON.parse(body),
})
}
});
});
};
exports.main = main;
it returns
Promise { < pending > }
undefined
However when I just use console.log(body), it gives the correct result
..................
.................
....
.....
.....
.....
Actually it it works correct and returns Promise.
So if you want to get "data" from promise, you should use Promise.then()
Like in this example from MDN.
const promise1 = new Promise(function(resolve, reject) {
resolve('Success!');
});
promise1.then(function(value) {
console.log(value);
// expected output: "Success!"
});
Hope it helps!