Axios Bad Request 400 - javascript

That is my axios code but is throwing me a error of Request failed with status code 400
import axios from "axios";
import { BASE_URL } from "../../enums/baseUrl";
import { UploadUrls } from "../../enums/imageupload/urls";
import { axiosInstance } from "../config";
export const upload = async (formData: FormData
): Promise<string> => {
const { data } = await axiosInstance.post(
`${BASE_URL.DEVELOPMENT}/${UploadUrls.UPLOAD}`, formData, {
headers: { 'Authorization': 'Bearer ************',
'Content-Type': 'multipart/form-data' },
transformRequest: formData => formData,
});
return data;
};

Related

Can axios request wait until the response is received?

I need to get IP address and port number details from an external source. These details are required to make some other requests. Following is the code I am trying on:
import axios from 'axios'
let ServerURL
axios.get('http://some/path')
.then((response) => {
ServerURL = 'http://' + response.data.server_ip_address + ':' + response.data.server_ip_port
})
.catch((error) => {
console.log(error)
})
const apiClient = axios.create({
baseURL: ServerURL,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
export default {
getConfigInfo () {
return apiClient.get('/config')
}
}
My problem is that by the time the exported function getConfigInfo() is called, still, the ServerURL is undefined.
How can I handle this kind of problem? Any help is highly appreciated.
Yes you can:
import axios from 'axios'
let apiClient;
const getApiClient = async () => {
if (apiClient) {
return apiClient;
}
const {
data: {
server_ip_address: ipAdress,
server_ip_port: ipPort,
}
} = await axios.get('http://some/path');
const serverUrl = `http://${ipAddress}:${ipPort}`;
apiClient = axios.create({
baseURL: ServerURL,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
});
}
export default {
async getConfigInfo() {
const apiClient = await getApiClient();
return apiClient.get('/config')
}
}
Pattern used: singleton

Make API handler wrapper to reduce repetition

Right now to call a private endpoint I need to copy this code to each component. Which is messy, unsustainable, and error-prone. How would I wrap this behavior in a function call and put it where I want utilities to go? So I could import { ApiUtil } from .. and ApiUtil.post('/user', user)
import axios from 'axios';
import { useAuth0 } from '../../../react-auth0-spa';
const authContext = useAuth0();
const {
getTokenSilently
} = authContext;
const token = await getTokenSilently();
await axios({
method: 'post',
headers: {
Authorization: `Bearer ${token}`,
},
url: '/user',
data: user,
});
You can create a instance of axios and can be reused in each component
import axios from 'axios';
//token code sample
const instance = axios.create({
baseURL: API_URL,
headers: { Authorization: `Bearer ${token}` }
});
export default instance;
You could create a new file and export an instance of axios
// ApiUtil.js
import axios from 'axios';
import { useAuth0 } from '../../../react-auth0-spa';
const authContext = useAuth0();
const { getTokenSilently } = authContext;
const token = await getTokenSilently();
export default axios.create({
headers: {
Authorization: `Bearer ${token}`,
},
});
Then, you could use it like this:
import ApiUtil from './ApiUtil';
// …
await ApiUtil.post('/user', { user });

How to mock axios dependency using mocha in TypeScript?

Here is my sample src/main.ts file
import axios from 'axios';
export async function main() {
const URL = 'test url';
const secretKey = 'Test key'
const response = await axios.get(URL, {
headers: { 'Content-Type': 'application/json', 'KEY': secretKey },
});
I want to write my test case in spec/test.ts file using mocha. Can someone show me how to create a mock and stub for axios dependency.
For mock/stub axios in typestript I recommend axios-mock-adapter, for expect functions chai
Here is an example of how to do this
request.ts
import axios from 'axios';
const apiConfig = {
returnRejectedPromiseOnError: true,
timeout: 30000,
headers: {
common: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
},
};
const request = axios.create(apiConfig);
export default request;
main.ts
import request from './request';
export const URL = 'https://httpbin.org/get';
export const secretKey = 'secret_key';
export async function main() {
const response = await request.get(URL, {
headers: {
KEY: secretKey,
},
});
// response logic
return response;
}
main.spec.ts
import MockAdapter from 'axios-mock-adapter';
import { expect } from 'chai';
import request from './request';
import { main, URL, secretKey } from './main';
describe('Request test', () => {
let stub: MockAdapter;
const receivedData = { data: 'data' };
before(() => {
stub = new MockAdapter(request);
stub.onGet(URL, {
headers: {
KEY: secretKey,
},
}).replyOnce(200, receivedData);
// replyOnce if you assume that your code sends a single request
});
it('test', async () => {
const response = await main();
expect(response.status).to.be.equal(200);
expect(response.data).to.be.deep.equal(receivedData);
});
after(() => {
stub.restore();
});
});

Post action API with object parameter within the URL

I've got an API where some of the parameters need to be given within the URL.
Example of how my api url looks like: https://www.server.com/api/actions/execute?auth_type=apikey&data={"Name": "name","Email" : "email"}
What my code looks like right now
register = async () => {
let data = {"Name":this.state.name, "Email":this.state.email}
data = JSON.stringify(data)
let URL = 'https://www.server.com/api/actions/execute?auth_type=apikey&data=';
fetch(URL, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: data
})
.then((response) => response.text())
.then((responseText) => {
alert(responseText);
})
.catch((error) => {
console.error(error);
});
}
The response I get on my device:
{"code":"succes","details":{"userMessage":["java.lang.Object#2e56000c"],"output_type":void","id:"20620000000018001"},"message":"function executed succesfully"}
This is alle working fine when I test it in postman but I can't get it to work within React-Native. I've tried stuff like 'Content-Type':'application/x-www-form-urlencoded' already.
First install the package axios from the url https://www.npmjs.com/package/react-native-axios
Then create two service for handling get and post request so that you can reuse them
GetService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const GetService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.get(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
PostService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const PostService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.post(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
Sample code for using get and post services is given below
import { PostService } from './PostService';
import { GetService } from './GetService';
let uploadData = new FormData();
uploadData.append('key1', this.state.value1);
uploadData.append('key2', this.state.value2);
//uploadData.append('uploads', { type: data.mime, uri: data.path, name: "samples" });
let jwtKey = ''; // Authentication key can be added here
PostService(uploadData, 'postUser.php', jwtKey).then((resp) => {
this.setState({ uploading: false });
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
GetService({}, 'getUser.php?uid='+uid, jwtKey).then((resp) => {
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
If you need to pass parameters via URL you should use GET, if you use POST then the parameters should be passed in the body

AsyncStorage.getItem returning undefined when using fetch - React-Native

I'm trying to set a token in my SignIn component using a promise and AsyncStorage but when I go to retrieve the token for use in a different component I get the error Cannot read property 'getItem' of undefined. I tried using Async/Await to wait for the token response in order to save it to storage but i've been getting the same error. How can I properly set the token?
SignIn.js Component
//Function is bound
async signIn() {
const data = JSON.stringify({username: this.state.username, password: this.state.password})
await fetch(`https://somesecretdomain.com:8443/users/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: data
}).then((response) => response.json()).then(async(responseJson) => {
AsyncStorage.setItem('jwt', responseJson.id_token);
const resetAction = NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({routeName: 'Profile'})]
});
this
.props
.navigation
.dispatch(resetAction);
}).catch((error) => {
console.warn(error);
})
};
Profile.js Component
async fetchData() {
AsyncStorage
.getItem('jwt')
.then((value) => {
this.setState({"TOKEN": value});
})
.done();
console.log(this.state.TOKEN)
const response = await
fetch(`https://somesecretdomain.com:8443/users/getUsers`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'token': this.state.TOKEN
}
})
const json = await response.json()
}
I changed the Profile.js component to below, still getting the same error.
import React, {AsyncStorage, localStorage} from 'react';
import {
Text,
View,
Image,
TouchableHighlight,
WebView,
TextInput,
KeyboardAvoidingView,
ScrollView
} from 'react-native';
async fetchData() {
const TOKEN = await AsyncStorage.getItem('jwt');
const response = await
fetch(`https://somedomain.com:8443/users/getUsers`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'token' : TOKEN
},
});
const result = await response.json();
this.setState({data: result})
}
Try this:
async signIn() {
const data = JSON.stringify({username: this.state.username, password: this.state.password})
const response = await fetch(`https://somesecretdomain.com:8443/users/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: data
});
const result = await response.json();
await AsyncStorage.setItem('jwt', result.id_token);
const resetAction = NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({routeName: 'Profile'})]
});
this
.props
.navigation
.dispatch(resetAction);
});
};

Categories

Resources