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