Fetching API and setting a variable to the res - node.js

const fetch = require('node-fetch');
let body = { a: 1 };
const stopId = 413
fetch(`https://api.ashx?stopId=${stopId}`, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
.then(json => body = json);
console.log(body)
I'm getting the output: { a: 1 } Instead of the API JsonResponse, however when I use .then(json => console.log(json)); I get the desired response..
I've tried to use await fetch, to pause the code till the promise returned then to console.log body but it needs to be an async function.. Does anyone know how I can assign the let body a new value before proceeding to the code below? Or would there be a way to return from .then ?
So I could do something like: (I know this doesn't work)
function fetchStop(stopId){
fetch(`https://api.ashx?stopId=${stopId}`, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
.then(json => return body);
}
console.log(fetchStop(stopId))
Any solutions or explanations/insights on how these things work is much appreciated, very much a noob with async and promises

The fetch executes asynchronously and you can access the result only in the callback.
Here, the console.log(body) executes soon after a network call is initiated.
const fetch = require('node-fetch');
let body = { a: 1 };
const stopId = 413
fetch(`https://api.ashx?stopId=${stopId}`, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
.then(json => body = json);
console.log(body)
To access the result,
function fetchStop(stopId){
return fetch(`https://api.ashx?stopId=${stopId}`, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
.then(res => res.json())
}
fetchStop(stopId).then(result => console.log(result))

You are using promise for fetching data from your URL https://api.ashx?stopId=${stopId}. Since this will take time and is asynchronous (nonblocking) so while it is fetching data code will move to console.log(body) and print the previous body (body = { a: 1 };). Because code flow moves to console.log before the promise gets executed, this promise will take time to fetch data. So you have to console.log within then itself. Because that's the point when your promise is getting executed later in time. You can do it easily using async await
const yourFunction = async () => {
const fetch = require('node-fetch');
let body = { a: 1 };
const stopId = 413;
const { hostname: location } = window.location;
const data = {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
}
const response = await fetch(`https://api.ashx?stopId=${stopId}`, data);
if (!response.ok) throw Error(response.message);
try {
body = await response.json();
return;
} catch (err) {
throw err;
}
};

Related

How can i optimize Azure Form Recognition response time?

I've implemented a custom model at Azures's form recognizer. In performance test, using PDF and JPEG files to do the text extraction, the hole process is being executed at Azure and are getting ~4.5s to response the requests.
My question is, There's a way to improve these response time?
There's my test code:
const processFile = (path) => axios({
url: RECOGNIZER_URL,
method: "POST",
headers: {
"Ocp-Apim-Subscription-Key": RECOGNIZER_KEY,
'Content-Type': `application/json`
},
data: {
"urlSource": path
}
})
const getResult = (location) => axios({
url: location,
method: "GET",
headers: {
"Ocp-Apim-Subscription-Key": RECOGNIZER_KEY
},
})
const testOcr = async (imageURL) => {
console.time('#testOcrTime');
let res = await processFile(imageURL)
.then(async response => {
let result = await getResult(response.headers["operation-location"])
while(((result.data) || {}).status == "running"){
result = await getResult(response.headers["operation-location"])
}
return result
})
.then(response => {console.log(response)
return response.data.analyzeResult.documents[0].fields})
.catch(err => console.error(err))
console.timeEnd('#testOcrTime');
console.log(res)
return
}
testOcr()
Azure's Documentation

How to send the result of a GET request in a POST request?

I need to send a GET request to https://random.dog/woof.json. It generate a random image and returns a json like this {
"fileSizeBytes": 1133380,
"url": "https://random.dog/8aff4e84-260d-4af0-9dc1-438d07ba3884.jpg"
} and I need save an image to my database. How can I take "url" and send it with POST request?
you can use node-fetch for server side requests.
It's similar to js' fetch api:
const fetch = require('node-fetch');
fetch('https://random.dog/woof.json')
.then(res => res.json())
.then(json => {
console.log("URL:", json[0].url);
fetch('<url for your post request>', {
method: 'POST',
body: { url: json[0].url },
headers: { 'Content-Type': 'application/json' }
}).then(postRes => postRes.json())
.then(postJson => console.log(postJson));
})
You can do something like that
const https = require('https')
function getData(url: String) {
const options = {
hostname: 'exemple.com',
path: '/your-endpoint',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
}
const req = https.request(options, (response: any) => {
let body = '';
response.on("data", (data: String) => {
body += data;
})
response.on("end", () => {
console.log(body)
})
response.on("error", (error: String) => {
console.error(error)
})
})
req.write(JSON.stringify({
url
}));
req.end()
}
https.get("https://random.dog/woof.json", (response: any) => {
let body = '';
response.on("data", (chunk: String) => {
body += chunk;
})
response.on("end", () => {
const obj = JSON.parse(body);
getData(obj.url)
})
});

when sending a request to the server, the node does not receive the req.body

when sending a request to the server, the node does not receive the req.body
what could be the mistake?
react:
sendRequest('POST','http://127.0.0.1:5500/api/auth/register', {...form})
function sendRequest(method:string, url:string, bodyObj:any = null){
return fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyObj)
}).then(response => response.json())
.then(result => result)
}
node:
router.post('/register',async (req,res)=>{
console.log(req.body)
res.status(200).json(req.body)
})
There are a few things going on here that might cause issues but I think the primary area to investigate is the sendRequest function is returning a Promise which is asynchronous but then it's also trying to .then within that same function.
Resolving or rejecting the return promise where you want to handle the data might be a better execution.
// This returns a Promise
function sendRequest(method, url, bodyObj) {
return fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyObj)
})
}
sendRequest('POST', 'http://127.0.0.1:5500/api/auth/register', { ...form
}).then(result => {
console.log(result)
}).catch(err => {
console.log(err)
})

The Fetch request does not return data

A snippet of code on the app side. I can't figure out exactly where my mistake is. It is possible that the helper change leaves the method before it has time to wait for a response from the server
Promise((resolve) => {
fetch('/currentDir1',{
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(elem)
})
.then(response => response.json())
.then(json => this.helper = json)
.then(json => this.$emit("newvalue", json))
console.log("helper");
console.log(this.helper);
resolve("result");
});
Server-side handler
router.post('/currentDir1',(req, res) =>{
console.log("POST");
let body = "";
let pathToFile = "";
req.on("data", function (data) {
body += data;
});
req.on("end", function(currentData) {
console.log(JSON.parse(body));
currentData = JSON.parse(body);
if(currentData.sizeOrType === "<папка>"){
let dir = currentData.dir + currentData.fileName;
// dir = "C:\\totalcmd";
console.log(dir);
if(currentData.whichScreen){
foo(dir, './data/firstScreen.json');
pathToFile = './data/firstScreen.json';
res.sendFile(path.resolve('./data/firstScreen.json'));
}else{
console.log('aaaa');
Foo(dir, './data/secondScreen.json');
pathToFile = './data/firstScreen.json';
res.sendFile(path.resolve('./data/secondScreen.json'));
}
}
// res.json({ message: 'goodbye'})
res.json(path.resolve(pathToFile));
});
res.sendFile(path.resolve(pathToFile));
})
Are you sure about the scope of this.helper? Try putting "this" into a variable outside the method to ensure the scope? i.e.
var that = this;
Promise((resolve) => {
fetch('/currentDir1',{
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(elem)
})
.then(response => response.json())
.then(json => that.helper = json)
.then(json => that.$emit("newvalue", json))
console.log("helper");
console.log(that.helper);
resolve("result");
});

How to convert fetch to axios

I have the following piece of code which is working perfect. However, my task is to replace fetch with axios. can you please guide, what would be the correct replacement of code in axios?
const create = async (credentials, software) => {
return await fetch('/api/software/create', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + credentials.t
},
credentials: 'include',
body: JSON.stringify(software)
})
.then((response) => {
return response.json()
}).catch((err) => console.log(err))
}
create({ t: jwt.token }, data)
.then((data) => {
if (data.error) {
this.setState({ error: data.error })
} else {
this.props.dispatch(initSoftware()); //if successful get the list of softwares in redux store
}
})
The data variable is an object which hold the req.body equivalent...
The above code is written in react and the create() is called within onSubmit eventhandler.
I am sure if I use axios the create() would be eliminated.. but how? Please guide..
It shouldn't be too different than what you currently have but something like this...
const create = async (credentials, software) => {
return await axios({
url: '/api/software/create'
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + credentials.t
},
withCredentials: true,
data: JSON.stringify(software)
})
.then((response) => {
return response.data;
}).catch((err) => console.log(err))
}
create({ t: jwt.token }, data)
.then((data) => {
if (data.error) {
this.setState({ error: data.error })
} else {
this.props.dispatch(initSoftware()); //if successful get the list of softwares in redux store
}
})
Note that the data you would be looking for should be in a property called data.
For more, check out the API references here.
2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.
I'm using jsonplaceholder fake API to demonstrate:
Fetch api GET request using async/await:
const asyncGetCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncGetCall()
Fetch api POST request using async/await:
const asyncPostCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
});
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncPostCall()
GET request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
POST request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
GET request using Axios:
const axiosGetCall = async () => {
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosGetCall()
POST request using Axios:
const axiosPostCall = async () => {
try {
const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts', {
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosPostCall()

Resources