What is the difference between these two Axios upload methods? - node.js

I have 2 different axios POST calls. The first one makes use of the .post method and this successfully uploads the image to the database.
return axios
.post("http://localhost:3000/api/v1/upload", data, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(response => {
console.log("The response", response);
})
.catch(error => {
console.log("Error", error);
});
However the method below does not seem to work properly and throws an error in the database / backend. But it does use the exact same configuration... :
Axios call that makes use of the Network utility function:
return httpPost(
process.env.NODE_ENV
? `https://tabbs-api.herokuapp.com/api/v1/upload`
: `http://localhost:3000/api/v1/upload`,
{
data
},
null
)
.then(response => {
console.log("uploaded", response);
})
.catch(error => {
console.log("Error", error);
});
Network Utility function:
export function httpPost(url, data, token) {
return axios({
method: "post",
url: url,
data: data,
headers: {
Authorization: "Bearer" + " " + token,
"Content-Type": "multipart/form-data"
}
});
}

Related

Unable to Fetch Response - 201 Message [duplicate]

This question already has answers here:
how to get data from response from fetch javascript request
(2 answers)
Closed 6 months ago.
I am trying to retrieve a response from an API using fetch in NextJS, I can get the message by calling the API but am unable to get anything using fetch. All I get from fetch is response 201 message that it's created.
When I run the API in postman I get the response:
{
"id": "21a1f0a6-f6c4-4aaf-9f48-2c9dba276646",
"status": "SUBMITTED"
}
But when I call the API using fetch in NestJS I get the response:
Response { type: "cors", url: "http://localhost:9000/api/v1/fireblocks/createTxnVaultToVault", redirected: false, status: 201, ok: true, statusText: "Created", headers: Headers, body: ReadableStream, bodyUsed: false }
Expected Behavior
The expected behavior is to get the same response as the API postman response. I need the tracking id to be passed into the UI
Backend - API Service & Controller Code in NestJS
Below is the API to run a transaction, it's coming from a NodeJS like framework (NestJS):
async createTxnVaultToVault(txn: Txn) {
this.logger.log("Creating transaction for account: " + txn);
this.logger.log("Transaction data: " + JSON.stringify(txn));
const payload: TransactionArguments = {
assetId: txn.asset,
source: {
type: PeerType.VAULT_ACCOUNT,
id: String(txn.source)
},
destination: {
type: PeerType.VAULT_ACCOUNT,
id: String(txn.dest)
},
amount: String(txn.amount),
fee: String(txn.fee),
note: txn.note
};
this.logger.log("TXN Payload data: " + JSON.stringify(payload));
return fireblocks().createTransaction(payload)
.then(res => res)
.then(res => {
console.log(res)
return res;
})
.catch(err => {
console.log(err);
return err;
});
}
Below is the controller to run a transactions, it's coming from a NodeJS like framework (NestJS):
#ApiTags('Fireblocks Transactions - Create Vault to Vault Transaction')
#Post('/createTxnVaultToVault')
async createTxnVaultToVault(
#Body() txn: Txn
): Promise<any> {
return this.appService.createTxnVaultToVault(txn)
.catch(e => {
this.logger.log(e);
return getError(e);
});
}
Frontend - Fetch Code in NextJS
export async function transferFunds(txn) {
const req_url = process.env.NEXT_PUBLIC_FIREBLOCKS_SERVER + "/createTxnVaultToVault";
console.log(txn);
return fetch(req_url, {
method: 'POST',
headers: {
Accept: "application/json",
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(txn)
})
.then(resp => {
console.log(resp);
})
.then(resp => {
console.log(resp);
return resp;
})
.catch(err => {
console.log(err);
});
}
It worked by changing how the UI received data. Below is how the API should be called:
Frontend - Fetch Code in NextJS
export async function transferFunds(txn) {
const req_url = process.env.NEXT_PUBLIC_FIREBLOCKS_SERVER + "/createTxnVaultToVault";
console.log(txn);
return fetch(req_url, {
method: 'POST',
headers: {
Accept: "application/json",
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(txn)
})
.then( async resp => {
//console.log(await resp.json())
return await resp.json();
})
.then(data => {
console.log(data);
return data;
//return data;
});
}

'Axios' show Error: Network Error on server returning with 200 http status

I am using axios: "^0.19.0" to create get and post requests in react-native 0.60.4, but even after backend returning HTTP status code 200 axois showing Error: Network Error. Working perfectly on iOS but not on Android.
My request:
export default function uploadImageWithData(formData, url = "createGroup") {
return new Promise((resolve, reject) => {
axios({
method: "post",
url: BASEURL + "api/webservice/" + url,
data: formData,
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${global.authToken}`
}
})
.then(response => {
resolve(response);
})
.catch(err => {
console.log("error: ", err);
reject(err);
});
});
}
Kindly help.
The issue with formData, in formData empty array appending in formData causing the issue(For Android).

How can I correctly make the fetch api call in react?

I wanted to fetch the result from the dummy API with react js using fetch. But I'm getting the error of "SyntaxError: Unexpected token < in JSON at position 0" from console.log()
handleSubmit(event) {
fetch({
url:'http://dummy.restapiexample.com/api/v1/employees',
mode: 'cors',
method: 'GET',
dataType: 'json',
headers: {
'Access-Control-Allow-Origin':'*',
'Content-Type': 'multipart/form-data'
}
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
event.preventDefault();
}
Fetch's first argument is 'url' and second argument is 'options'.Try out this one:
handleSubmit(event) {
fetch('http://dummy.restapiexample.com/api/v1/employees', {
mode: 'cors',
method: 'GET',
dataType: 'json',
headers: {
'Access-Control-Allow-Origin':'*',
'Content-Type': 'multipart/form-data'
}
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
event.preventDefault();
}
Seems like you are getting 404 response which is giving error while converting to json.
I have printed response before converting to json in below code. Check your console after running code.
fetch({
url:'http://dummy.restapiexample.com/api/v1/employees',
mode: 'cors',
method: 'GET',
dataType: 'json',
headers: {
'Access-Control-Allow-Origin':'*',
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
console.log(response);
response.json()})
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
I usually get this error when I have a problem on the backend. Check if on the backend your API is returning the data in a json format.
Here is the updated one
fetch('http://dummy.restapiexample.com/api/v1/employees')
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log("result",data);
});
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
I would prefer to use with Axios as its best recommended and suited for react applications.
axios.get( 'http://dummy.restapiexample.com/api/v1/employees')
.then( response => {
console.log("result",response.data)
} )
.catch( error => {
console.log("error",error)
} );
This happens when you make a request to the server and parse the response as JSON, but it’s not JSON.
fetch('http://dummy.restapiexample.com/api/v1/employees').then(res => res.json())
The actual request worked fine. It got a response. But the res.json() is what failed.
Read this for more suggestion

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()

incorrect behaviour of node-fetch while trying to get token from an api

I want to connect to an external api using some node-fetch code. My code first sends the login details & should receive a token from the api. Then this token is used for all the later communications.
Here is the code :
import fetch from 'node-fetch';
function getTokenForAuth(info) {
try {
var auth_token = '';
fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
.then(function(json) {
auth_token = json;
})
return auth_token.token;
}
catch (e) {
console.log('[-] Error: Token Not Received');
console.log('[!] Exception: ' + e);
}
}
function getJSONFromRelativeURL(relativeURL, info) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + getTokenForAuth(info)
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
In the getJSONFromRelativeURL() function's request headers, if I hardcode the token, I get correct results. But if I run the code as it is now, I get an error saying : { detail: 'Invalid token.' }.
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called. I am not sure about this hypothesis & don't know how to correct this.
Your problem is here:
.then(function(json) {
auth_token = json;
})
return auth_token.token;
Your return statement is outside the Promise chain. This means that, at the point you hit return, the fetch request hasn't had a chance to even run yet. You've essentially just told the fetch Promise chain what to do when it does return.
So essentially
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called.
is 100% correct.
What you'll need to do is restructure things a little bit:
function getTokenForAuth(info) {
return fetch(api_url + "/api/api-token/", {
method: "POST",
body: JSON.stringify(info),
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
}).then(function(res) {
return res.json();
});
}
function getJSONFromRelativeURL(relativeURL, info) {
return getTokenForAuth(info)
.then(function(token) {
return fetch(`${api_url}${relativeURL}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${token}`
}
});
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
});
}
Have not tested it but it looks something like the following. For error handling use .catch(()=>{}) at the end of each chain.
function getTokenForAuth(info) {
var auth_token = '';
return fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
}
function getJSONFromRelativeURL(relativeURL, info, token) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + token
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
getTokenForAuth(info)
.then((token)=>{
return getJSONFromRelativeURL(relativeURL, info, token)
})

Resources