async function returns Promise { <pending> } - facebook

I am trying to write a function that takes a URL and returns the engagement stats from Facebook Graph API against that URL. But I am facing trouble as my function is just giving me Promise { <pending> } as output.
Here is my code:
const getFacebookStats = async (link, ACCESS_TOKEN) => {
try {
const resp = await axios.get(
`https://graph.facebook.com/v12.0/?id=${link}&fields=engagement&access_token=${ACCESS_TOKEN}`
);
return resp;
} catch (err) {
// Handle Error Here
console.error(err);
}
};
Any help would be much appreciated.

Call your function like this:
getFacebookStats(link, ACCESS_TOKEN).then(response => {
console.log(response);
}).catch(error => {
console.error(error);
});
Or you could call it using await inside an async function.
Check this answer for a more detailed explaination of Promises in javascript.

Related

axios how get status error without response

How can i get information about the error when there is no responce in the error? Through postman I see code 404, through catch I see code 0 in the request. How can I get 404 code?
(async () => {
try {
const res = await axios('https://ms.com/s');
}
catch(e) {
console.log(e);
console.log(e.response);
console.log(e.request);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js"></script>
var response = await axiosbase.get('https://ms.com/s')
.then(response => {
return response;
}).catch(response => {
return response;
});
if(response.status === 200){
// do something here.
}

HTTP .get() method does not respond with anything

I am trying to use Express + MongoDB building React app.
I was able to post some documents to MongoDB and delete them. Currently, I'm trying to figure out how to get them using HTTP .get() method.
I have these routes:
router.post('/totalbalance', (request, response) => {
const totalBalance = new TotalBalanceModelTemplate({
totalBalance:request.body.totalBalance,
});
totalBalance.save()
.then(data => {
response.json(data);
})
.catch(error => {
response.json(error);
});
});
router.get('/totalbalance', (request, response) => {
console.log("Response ", response);
});
This is axios request:
useEffect(() => {
console.log("Using get() method here");
axios.get('http://localhost:4000/app/totalbalance')
}, []);
However, it does not return anything (only 'Using get() method here' gets printed out to the console).
What am I missing here?
Thanks in advance!

detecting error for Nextjs API route with Axios

I am using nextjs api/routes
I have a login and when an issue occurs return a 401 and message text that I would like to show to users.
A minimal example is:
Api : /api/v1/auth/sigin.js
export default async (req, res) => {
const { name, password } = req.body;
const url = process.env.SH_API_BASEURL + 'auth/signin';
console.log(url);
try {
const resp = await axios.patch(url, { name, password });
return res.status(200).send(resp.data);
} catch (err) {
const { response } = err;
const status = response.status;
const message = response.data.errors[0].message;
console.log(`status: ${status}, message ${message}`);
return res.status(status).send(message);
}
};
Pages /pages/auth/signin.js
const handleFormSubmit = async (formData, e) => {
e.preventDefault();
try {
const res = await axios.post('/api/v1/auth/signin', formData);
router.push('/secure/home');
} catch (err) {
console.log('pages auth in error');
console.log(err);
setSubmitError(true);
console.log('sigin handle submit error');
}
};
console.log(err) shows the output
Error: Request failed with status code 401
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
How do I get access to the statusCode and text in pages code?
Could any answers be in the context of nextjs api/routes
Thanks
You can access the response property of the axios error to get the status
const handleFormSubmit = async (formData, e) => {
e.preventDefault();
try {
const res = await axios.post('/api/v1/auth/signin', formData);
router.push('/secure/home');
} catch (err) {
console.log(err.response.status);
}
};

Axios get request with parameter is not working

I am passing a parameter to the axios get request. It works on postman properly but does not work with my code. I don't know where I am making a mistake.
I want only one specific data from db but I am receiving all the data in available in the collection. But with postman I get the desired data
backend route :
router.get('/displayUser', (req,res) => {
const query = user = req.body ;
Services.find(query)
.exec((err, services) => res.json(services))
})
axios call : I tried two different ways and both didn't work
method 1:
getData: async function () {
const user = this.userId
console.log(user)
let res = await axios.get('http://localhost:5000/api/services/displayUser' , { params: { user }})
console.log(res.data);
}
method 2:
getData: async function () {
var data = JSON.stringify({"user":this.userId});
console.log(data)
var config = {
method: 'get',
url: 'http://localhost:5000/api/services/displayUser',
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
}
When I get the data in console I am getting all 3 objects available in collection instead of the specific one related to the user Id
Screenshot
But in postman It works as desired
screenshot
I do this as following:
when I need a get :
app.get('/detail/:id', function (req, res) {
//console.log(req.params.id);
var url=urlDetail + "/" + req.params.id;
axios.get(url)
.then(function (response) {
// result=response.data;
res.render('database', { title: 'Detail' , dbs: response.data ,Version:pjson.version});
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
//console.log("ici always");
});
});
and when i need to post (req.body is a json):
app.post('/carto/demande', function (req, res) {
let data;
console.log(req.params);
console.log(req.body);
var url=urlCartoDemande;
axios.post(url,req.body)
.then(function (response) {
data=response.data;
res.render('carto', { title : 'Demande' ,Version:pjson.version,mode:"resultat",data:data } );
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
});

Why resolving an async promise with a .map() function doesn't work for GET with parameters?

I am not sure how to express my question correctly.
Basically resolving an async promise with a .map() function works for simple get functions while it doesn't work for get functions with parameter.
Basically, in this case, router.get('/' ... the following works:
import axios from 'axios'
const url = 'http://localhost:3000/api/library/'
class libraryService {
// Get stories
static getStories () {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url)
const data = res.data
resolve(
data.map(story => ({
...story
}))
)
} catch (err) {
reject(err)
}
})
}
export default libraryService
While in this case, router.get('/:story_name' ..., this variation doesn't work:
class readService {
// Get story to read
static getStoryToRead (storyName) {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url + storyName)
const data = res.data
resolve(
data.map(selectedStory => ({
...selectedStory
}))
...
In here I get an error: 'data.map is not a function'.
Changing to data.products.map() will return an error 'Cannot read property 'map' of undefined'.
However resolving data without .map() function will work on all cases:
try {
const res = await axios.get(...)
const data = res.data
resolve(
data
)
...
Why this is happening and is it correct to just use resolve(data)?
You seem to be asking for a single story in the case that doesn't work. So instead of an array of stories, presuambly you're getting just the one story that you asked for. There's no reason to try to use map.
Minimal changes (but keep reading):
// Minimal changes, but keep reading...
static getStoryToRead (storyName) {
return new Promise(async (resolve, reject) => {
try {
const res = await axios.get(url + storyName);
resolve(res.data);
} catch (err) {
reject(err);
}
});
}
But, both of those functions demonstrate the Promise creation antipattern. You already have a promise, work with it. In this case, you'd probably do that by making the functions async:
static async getStories () {
const {data} = await axios.get(url);
return data.map(story => ({ // Why copy the story objects?
...story
}));
}
static async getStoryToRead (storyName) {
const {data} = await axios.get(url + storyName));
return data;
}
Or with non-async functions:
static getStories () {
return axios.get(url)
.then(({data}) => data.map(story => ({...story}))); // Why copy the story objects?
}
static getStoryToRead (storyName) {
return axios.get(url + storyName))
.then(({data}) => data);
}