Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Following is the code where I use async await to fetch a token, which is the used to make another request.
But the issues is that even though I'm doing it as one by one async await request, the token is not getting defined before the second async call is made.
So I'm getting a big fat error.
try {
const access = await superagent
.post("https://token-link.com/token")
.send(
"apikey=" + API_KEY
)
.set("Content-Type", "application/x-www-form-urlencoded")
.set("Accept", "application/json");
const token = access.body["access_token"];
// console.log(token) -- > here I'm doing a console log and I'm being able to see the token.
// But when the following request is made right after the above one, I'm getting an error.
const report = await superagent
.post(
"https://another-link/api/v2/data"
)
.set("Accept", "application/json")
.set("Authorization", "Bearer " + token)
.set("Content-Type", "application/json;charset=UTF-8")
.send(
JSON.stringify(data)
);
res.send(report);
// also when I do a console.log(report.body.data) --> then also I'm getting an error...
} catch (e) {
res.status(400).json({ error: e });
}
Now If I do a curl request and store the token as a constant before making the second request, then the error is gone.
So I assume that the first request is not fullfilled before the second one is made.
Can someone help?
try {
const token = "eyJraWQiOiIyMDIxMDQyMDE4MzYiLCJhbGciOiJSUzI1NiJ9.eyJpYW1faWQiOiJJQk1pZC01NTAwMDlFUzY5IiwiaWQiOiJJQk1pZC01NTAwMDlFUzY5IiwicmVhbG1pZCI6IklC"
// If the token is stored as a constant then there is no error.
const report = await superagent
.post(
"https://another-link/api/v2/data"
)
.set("Accept", "application/json")
.set("Authorization", "Bearer " + token)
.set("Content-Type", "application/json;charset=UTF-8")
.send(
JSON.stringify(data)
);
res.send(report);
} catch (e) {
res.status(400).json({ error: e });
}
IS my async await working as expected or am I missing something?
If you can't figure it out from comments (but your code should work just fine), to answer your question you have 2 choices:
In first promise's then call the second (works fine on your code but does not scale)
Use async.waterfall
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 months ago.
Improve this question
I am new to Express.js and am trying to create a URL shortener.
When the user naviagtes to domain.com/r/ I query the DB for the param and get the actual URL.
I use res.redirect to try to redirect to their stored URL but it fails with 'res.redirect is not a function'.
Please see the snippet below:
router.get('/r/:shortUrl', function(req, res) {
connectDatabase.then(
checkDatabase(req.params.shortUrl)
.then( res => {
console.log('checkdatdabase res => ' + res); //res = 'https://www.google.com'
res.redirect(res); //TypeError: res.redirect is not a function
})
.catch(e => {
//executed due to above error
console.error(e);
res.redirect(307, '/home');
})
)
});
Any advice would be much appreciated as this is a learning project for me.
You have two variables named res.
One, passed to the callback you pass to get() is a response object which has a redirect method.
The other is the resolved value of checkDatabase and is not a response object.
The latter has shadowed the former so you can't access it any more.
Use unique names for your variables to avoid this problem.
I recommend using a linter. ESLint can catch this kind of problem with the no-shadow rule.
datdabaseRes and res should be different variable name. Otherwise res has the respose object of database connection in the scope you are trying to use it.
router.get('/r/:shortUrl', function(req, res) {
connectDatabase.then(
checkDatabase(req.params.shortUrl)
.then( datdabaseRes => {
console.log('checkdatdabase res => ' + datdabaseRes); //res = 'https://www.google.com'
res.redirect(datdabaseRes); //TypeError: res.redirect is not a function
})
.catch(e => {
//executed due to above error
console.error(e);
res.redirect(307, '/home');
})
)
});
I am new to node.js and APIs so I am hoping someone can help! I am trying to use node-fetch to get JSON data from the fantasy premier league API. I have successfully done this in the client, but from my node.js server file I keep getting the error:
UnhandledPromiseRejectionWarning: FetchError: invalid json response
body at https://fantasy.premierleague.com/api/entry/3/ reason:
Unexpected end of JSON input
The response itself has a status of 200, but the size is 0 so it is not returning any data. I know it should work, as the JSON is plainly visible when you visit the url and I have got fetch to work in the client-side code.
Here is the code I am using:
const fetch = require('node-fetch');
async function fetchEntry() {
const api_url = 'https://fantasy.premierleague.com/api/entry/3/';
const fetchEntry_response = await fetch(api_url);
const json = await fetchEntry_response.json();
console.log("json: " + JSON.stringify(json));
};
fetchEntry();
Note: On the client-side code I got a CORS error so needed to use a proxy (https://thingproxy.freeboard.io/fetch/https://fantasy.premierleague.com/api/entry/3/) to get it to work. I'm not sure if this is relevant?
Any help would be greatly appreciated!
Joe
Don't ask me why but adding a 'User-Agent' header seems to fix it:
const response = await fetch(URL, {
headers: {
'User-Agent': 'ANYTHING_WILL_WORK_HERE'
}
});
I think the api you're using is the problem. I tried to make it work, but got the same error. Also tried to use axios but it's the same thing.
I tried to fetch data with Postman and it worked perfectly, so.. my guess is that the api you're trying to use does not support all origin, since the API I tried to use works perfectly with your code.
const api_url = "https://randomuser.me/api";
I was facing the same problem when running the test cases. In my test case, there was the API call and I have used the useEffect react hook for updating the state.
useEffect(() => {
getDetailsFromAPI("param")
}, []);
So, While running the test case, I was getting the same error
FetchError: invalid json response body at reason: Unexpected end of JSON input
at ../../node_modules/node-fetch/lib/index.js:272:32
For solving this error I have mock the promise in the test case, which resolved my issue.
import fetch from 'node-fetch';
const mockJsonPromise = Promise.resolve(mydata); // 2
const mockFetchPromise = Promise.resolve({ // 3
json: () => mockJsonPromise,
ok: () => true
});
fetch.mockImplementation(() => mockFetchPromise);
I'm making an XMLHttpRequest via POST method and then trying to get the tokenid to verify it in my node.js file. However, I keep on getting an error when I try to verify the token. I get an error saying:
Error: First argument to verifyIdToken() must be a Firebase ID token string
This is how I'm making the POST request:
var xhr = new XMLHttpRequest();
xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded"
);
xhr.onload = function() {
console.log("Signed in as: " + xhr.responseText);
};
xhr.send("idtoken=" + user.getIdToken());
This is my code for the node.js file:
app.post("/tokensignin", (req, res) => {
admin
.auth()
.verifyIdToken(req.body.idtoken)
.then(function(decodedToken) {
let uid = decodedToken.uid;
console.log("uid is " + uid);
})
.catch(function(error) {
console.log(error);
});
});
I have tried using req.body, and req.body.token, but the error persists. When I try to print the idtoken, I get [Object object]
You are sendinging data using the field name called "idtoken":
xhr.send("idtoken=" + user.getIdToken());
But you are accessing it on your backend using a different name "token":
.verifyIdToken(req.body.token)
I suggest doing more logging in general in order to better understand what you're working with on both sides and debug what's going on.
What do you get when logging the request.body object? You have nodejs body parser installed, right? Are you using your own NodeJS server (I am almost certain you do)? But my question is why not use the Firebase environment?
everyone!
I got a problem: I'm trying to validate registration form. Totally, it works ok, but I need to validate form via server. In my case, for example, I need to figure out if email is already taken.
I tried to fetch and async/await syntax, but problem is still the same:
DOMException: "The operation was aborted. "
The way I understand it right now is readableStream (what actual response body is) is locked. So the wrong error is thrown, and I cannot get server response.
try {
const response = await fetch(options.url, options.requestOptions);
const body = await response.json();
if (options.modifyDataCallback instanceof Function) {
body.data = options.modifyDataCallback(body.data);
}
return body.data;
} catch (error) {
throw error;
}
How do I see the solution? I send request and recieve some server error like
code: email_in_use
message: Email '...' is already in use.
Then I need to throw error and catch it in other place in order to show corresponding error message to client.
In browsers network tab I do receive what I want to receive, but can't get the same JSON-response in my code.
Google chrome provided more information: net::ERR_HTTP2_PROTOCOL_ERROR 200.
And the problem was on backend. It is written in C# and API method returned Task. The problem was solved by adding async/await for this method.
I'm new to NodeJS and I am currently working on getting an API working. Currently running is Express for that purpose and i really would like to stick to express to solve it.
My goal is to let other people send me their data through links (Example would be: http://localhost:1000/api/?product=test) so i can just grab them with a simple 'var productname = req.param('product'); That part works just fine.
But i would like to simply call a method to send data from my server, meaning i would like to trigger sending the data with a function and then send the data as a link to another server. (Example would be to http://google.com/search?q=test)
I can't seem to get it to work even if i directly work with the documentation from express: https://nodejs.org/api/http.html#http_http_get_url_options_callback
Could anyone point me in the right direction?
If i try the code snippet below, I'm not even getting a console.log.
My current code attempt is:
// testing purpose to call the method and get a console log
sendServerUpdates('chair');
function sendServerUpdates(product){
url = 'google.com/';
app.get(url + 'search', (res) => {
const {statusCode} = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' + `Status Code:
${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' + `Expected
application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
// Information for me that the system is sending a message
console.log('sending update');
// sending (if its working) the parameter product
res.status(200).send(product);
})
}
}