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);
});
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();
I need to configure the base url of my endpoints after I make successful http requests (status code: 200).
I've written the below function but it's not working as I was expecting... It always returns undefined. I know it's something about promises but I don't have much experience.
const get = require('./functions/functionGET');
function geturl() {
var baseip;
get(
"username",
"password",
"http://**.***.**.35:8048/TESTDEV02/ODataV4/Company"
)
.then((response) => {
if (response.statusCode === 200) {
baseip = "http://**.***.**.35:8048/TESTDEV02/ODataV4/Company('*******')";
} else {
get(
"username",
"password",
"http://**.***.**.36:8048/TESTDEV02/ODataV4/Company"
).then((response) => {
if (response.statusCode === 200) {
baseip = "http://**.***.**.36:8048/TESTDEV02/ODataV4/Company('*******')";
} else {
get(
"username",
"password",
"http://**.***.**.37:8048/TESTDEV02/ODataV4/Company"
).then((response) => {
if (response.statusCode === 200) {
baseip = "http://**.***.**.37:8048/TESTDEV02/ODataV4/Company('*******')";
}
});
}
});
}
})
console.log(baseip)
return baseip;
}
module.exports = geturl();
EDIT
This is the get() function:
const { promisify } = require('util');
var httpntlm = require('httpntlm');
const Logger = require('../../services/error_logger')
const logger = new Logger('app')
module.exports = function (username, password, url) {
var httpntlmGetAsync = promisify(httpntlm.get);
return httpntlmGetAsync({
url: url,
username: username,
password: password,
workstation: '',
domain: '',
headers: {
'Access-Control-Allow-Origin': '*',
'Accept': '*/*',
'Content-Type': 'application/json; charset=utf-8'
}
})
.catch(err => logger.error(`URL: ${url}, Error: ${err}`))
then(response => {
return response.body
});
};
Looks like you need to put await before each get() method. At the same time you have to declare your function as async:
async function geturl() { //...
Without an await the next line of you code after get() gets executed regardless if get() returned anything yet. Therefore baseip is left as undefined.
EDIT: this is assuming your get() method from ./functions/functionGET is asynchronous.
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)
}
);
}
I'm calling two methods in useeffect but when api1 get called it get executed till await axios.put and then api2 get called without getting the response from api1. And after getting a reponse from api2 it goes to api1 reponse and gets a reponse as undefined
useEffect(() => {
api1();
api2();
}, [])
const api1 = async () => {
try {
var requestModel = JSON.stringify({ UserId: userid, MenuName: menuname });
var requestBody = security.encrypt(requestModel);
axios.myHashData = security.computedHmac256(requestBody);
var config = { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } }
await axios.put(axios.controllername + 'methodname', requestBody, config, { withCredentials: true })
.then(response => {
if (response.status === 200) {
//setapidata(response.data);
}
});
} catch (error) {
console.error(error.message)
}
}
const api2= async () => {
try {
var requestModel = JSON.stringify({ UserID: userid });
var requestBody = security.encrypt(requestModel);
axios.myHashData = security.computedHmac256(requestBody);
var config = { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } }
await axios.post(axios.controllername + 'methodname', requestBody, config, { withCredentials: true })
.then(response => {
if (response.status === 200) {
setapidata(response.data);
GetApis();
}
});
} catch (error) {
console.error(error.message)
}
}
If you want to wait for the api1 to execute before api2 is called you need to change the code for useEffect as below
useEffect(async() => {
await api1();
await api2();
}, [])
or
useEffect(() => {
api1().then(() => api2());
}, [])
To handle errors properly use try-catch block inside the useEffect if using await or use catch block if using .then
Also, another suggestion, if you are using a function inside useEffect make sure either the function is defined inside the same useEffect block or it is memorized either via useCallback or useMemo
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