Why does funtion in Node return undefined? - node.js

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.

Related

Implementation of rxjs BehaviourSubject in Next.js for state management not working

Trying to store jwt token on login using rxjs behavioursubject
Then creating a http request with Authorization: Bearer ${user.jwtToken} in the
I believe I need to have
a) initial value,
b) a source that can be turned into an observable
c) a public variable that can be subscribed
On log in the user is correctly added to the user subject here "userSubject.next(user);"
But whenever I try to create the bearer token its always null
// The Accounts Service
// initialise and set initial value
const userSubject = new BehaviorSubject(null);
const authApiUrl = "https:testApi";
export const accountService = {
` user: userSubject.asObservable(), get userValue() { return userSubject.value },
login,
getAllUsers
};
function login(email, password) {
return fetchWrapper.post(process.env.AuthApiUrl + '/accounts/authenticate', { email, password })
.then(user => {
userSubject.next(user);
localStorage.setItem('user', JSON.stringify(user));
return user;
});
}
function getAllUsers() {
return await fetchWrapper.get(process.env.AuthApiUrl + '/accounts/get-all-users');
}
}
// The fetchwrapper
export const fetchWrapper = {
get,
post
};
function post(url, body) {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeader(url) },
credentials: 'include',
body: JSON.stringify(body)
};
return fetch(url, requestOptions).then(handleResponse);
}
function get(url) {
const requestOptions = {
method: 'GET',
headers: authHeader(url)
};
return fetch(url, requestOptions).then(handleResponse);
}
function authHeader(url) {
// return auth header with basic auth credentials if user is logged in and request is to the api url
// THE accountService.userValue IS ALWAYS NULL???
const user = accountService.userValue;
const isLoggedIn = user && user.jwtToken;
const isApiUrl = url.startsWith(process.env.AuthApiUrl);
if (isLoggedIn && isApiUrl) {
return { Authorization: `Bearer ${user.jwtToken}` };
} else {
return {};
}
}
function handleResponse(response) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
if ([401, 403].includes(response.status) && accountService.userValue) {
// auto logout if 401 Unauthorized or 403 Forbidden response returned from api
accountService.logout();
}
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
return data;
});
}

Return from module is undefined

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);
});

i'm getting isssue while calling API in Useeffect in reactJs

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

How to send parameters through axios get method in react?

I have a axios GET method and I need to pass parameters with the get request. I am calling the GET method in Client side (React.js) like this,
const [Cart] = useState([]);
const user = {
userId : session.userId
};
console.log(user);
useEffect((user) => {
if(session.userId !== null){
//Axios.get('http://localhost:5000/api/cart/getCart', user) <- I tried both these ways
Axios({
method: 'GET',
url: 'http://localhost:5000/api/cart/getCart',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: {},
params: {
"userId" : session.userId
}
})
.then(res => {
const cart = res.data;
let tempProducts = [];
cart.data.forEach(item => {
const singleItem = {...item};
tempProducts = [...tempProducts, singleItem];
});
this.setState(() => {
return {Cart: tempProducts};
});
})
}
console.log(Cart)
});
But in server side (node.js), it doesn't get the parameter value.
router.get('/getCart', (req, res) => {
console.log(req.body.userId) //This gives the output as undefined
User.findOne({_id: req.body.userId}
,(err, userInfo) => {
res.json(userInfo.Cart);
})
});
I implemented the uncommented axios.get request by referring to this. Can you please help me to find the error? Or can you suggest me any other method to do this? Thanks
UseEffect :
axios.get('/api', {
params: {
foo: 'bar'
}
});
Server :
function get(req, res, next) {
let param = req.query.foo
.....
}

Not return value from custom helper

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

Resources