(RN) Possible Unhandled Promise Rejection (id: 0): #Redux + axios - reactjs

function requestService() {
return axios.create({
baseURL: userEndpoint,
headers: {
common: {
Accept: 'application/json',
}
}
}).then(response => {
return response.json();
}).catch(error => {
console.log('requestService', error);
});
}
module.exports = {
requestService
};
RequestService.js
import type { PromiseAction } from "./Types";
async function loadHopses(userId: number): PromiseAction {
const url = `hopses/user/${userId}`
const list = requestService().get(url);
await InteractionManager.runAfterInteractions();
return {
type: "LOADED_HOPSES",
list
};
}
module.exports = {
loadHopses
};
Action.js
this.props.dispatch(loadHopses(1));
App.js
export type PromiseAction = Promise<Action>;
Types.js
error is
Possible Unhandled Promise Rejection (id: 0):
TypeError: _axios2.default.create(...).then is not a function
TypeError: _axios2.default.create(...).then is not a function
I based on f8 facebook app and be converting parse to rest
What's wrong in this code?
please help..

axios.create returns an instance like this:
var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
These are the only valid methods for that.
axios#request(config)
axios#get(url[, config])
axios#delete(url[, config])
axios#head(url[, config])
axios#options(url[, config])
axios#post(url[, data[, config]])
axios#put(url[, data[, config]])
axios#patch(url[, data[, config]])
You can instead use it like this:
return axios.({
method: 'post',
baseURL: userEndpoint,
headers: {
common: {
Accept: 'application/json',
}
}
}).then(...).catch(...);
Using axios() instead of axios.create()

Related

ApiClient - fetch returns [object Object]

I have an apiClient file which contains the generic get method below
export const API_URL = 'https://localhost:40000';
const query = async <T>(request: RequestInfo, options?: RequestInit): Promise<T> => {
return fetch(request, options).then(response => {
if (!response.ok) {
throw response;
}
return response.json();
});
};
export const get = async <T>(url: string): Promise<T> =>
query(`${API_URL}${url}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
mode: 'cors',
cache: 'default'
});
In my services, I have a function that calls the get method (fetch) and takes a string URL.
const getAllProjects = async () => {
try {
const response = await get<Response>('/Projects');
if (response.ok) {
const jsonData = await response.json();
const projects = await jsonData.data;
return projects;
}
console.log(response);
} catch (error) {
console.log(error);
}
};
However, the issue I am facing is when I call the query method in the generic get method, it returns [object Object]. I have tried to pass in a string URL and replace it with ${API_URL}${url} but this also returned the same outcome.

getStaticPaths returning posts.map is not a function

getStaticPaths returning posts.map is not a function error while fetch slug in next.js with the following code.
export async function getStaticPaths() {
var config = {
headers: {
accept: '*/*',
'Content-Type': 'application/json',
'API_ACCESS_KEY': 'hns2V0Ddbkkn8r1XLq3Kw7ZoiBTR0nmA',
}
}
const url = 'http://localhost:8000/api/snippets';
const res = await fetch(url,config);
const posts = await res.json();
const paths = posts.map((post)=>{
return {
params:{
sid:post.id.toString(),
}
}
});
return { paths, fallback: false }
}

Add Interceptors to instance of axios

I'm trying to update my app token on axios interceptors, using React Native. I have this code to connect to API back-end:
const requestHelper = axios.create({
baseURL: "http://192.168.0.15:8000/api/",
headers: {
"Content-Type": "application/json",
Authorization: "token 3260b30bdbc19a5c4deed87327536e443c751d27",
},
});
const routes = {
accounts: {
getUser: () =>
requestHelper({
method: "get",
url: "accounts/detail/",
}),
.....
This is working but the token is hardcoded. I now need to update that token from AsyncStorage every time an API call is requested. I was trying to use Axios interceptors but is not working. These are my tests:
const requestHelper = axios.create({
baseURL: "http://192.168.0.15:8000/api/",
headers: {
"Content-Type": "application/json",
},
});
const createInterceptors = (instance) => {
instance.interceptors.request.use(
(config) => {
config.headers = {
Authorization: "token 3260b30bdbc19a5c4deed87327536e443c751d27",
};
return instance;
},
(error) => {
return Promise.reject(error);
}
);
return instance;
};
const routes = {
accounts: {
getUser: () =>
createInterceptors(
requestHelper({
method: "get",
url: "accounts/detail/",
})
),
....
The token is hardcoded here too, but for testing purposes. This tests raise an error:
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'instance.interceptors.request')]
Does anyone know how this could be implemented?
I solved it. I have to add the interceptor function like this:
const requestHelper = axios.create({
baseURL: "http://192.168.0.15:8000/api/",
headers: {
"Content-Type": "application/json",
},
});
requestHelper.interceptors.request.use(async (config) => {
const token = await AsyncStorage.getItem("token");
config.headers = {
Authorization: "token " + token,
};
return config;
});

Make multiple axios calls using jest

I am working with rest js using typescript and I am trying to mock multiple API calls using jest for unit testing.
My api calls are in the following format:
await axios.request({
method: 'POST',
url: //api url,
data: {},
headers: {}
})
.then()
.catch()
I am mocking the axios as follows:
jest.mock('axios', () => {
return {
request: jest.fn().mockResolvedValue({
data: ['responseData', 'responseData1']
headers: //response header
})
}
});
The test case for api call is created as follows:
expect(axios.request).toHaveBeenCalled(); expect(axios.request).toHaveBeenCalledWith({
method: 'POST',
url: //api url,
data: {},
headers: {}
});
For multiple API calls, I am mocking it multiple times with different response data but it is taking the last mocked value as the response of all the API calls in the test cases.
for example: for multiple data mocks like:
jest.mock('axios', () => {
return {
request: jest.fn().mockResolvedValue({
data: ['responseData', 'responseData1']
headers: //response header
})
}
});
jest.mock('axios', () => {
return {
request: jest.fn().mockResolvedValue({
data: ['secondResponseData', 'secondResponseData1']
headers: //response header
})
}
});
when I am running the test cases I am getting the response for all my apis as:
data: ['secondResponseData', 'secondResponseData1']
headers: //response header
data: ['secondResponseData', 'secondResponseData1']
headers: //response header
instead of:
data: ['responseData', 'responseData1']
headers: //response header
data: ['secondResponseData', 'secondResponseData1']
headers: //response header
I don't know how to mock the correct response with the correct api call in the test cases. Is there any way that I can mock the correct response with the API calls?
Basic usage.
import * as axios from "axios";
// Mock out all top level functions, such as get, put, delete and post:
jest.mock("axios");
// ...
test("good response", () => {
axios.get.mockImplementation(() => Promise.resolve({ data: {...} }));
// ...
});
test("bad response", () => {
axios.get.mockImplementation(() => Promise.reject({ ... }));
// ...
});
With response code.
axios.get.mockImplementation(() => Promise.resolve({ status: 200, data: {...} }));
Based on parameters.
axios.get.mockImplementation((url) => {
if (url === 'www.example.com') {
return Promise.resolve({ data: {...} });
} else {
//...
}
});
Try something like this:
axiosPostSpy = jest.spyOn(axios, 'post').mockImplementation((url) => {
if( url === 'www.test.com?key=serverKey') {
return {
data: {
success: false,
},
};
} else {
return {
data: {
success: true,
},
};
}
});

Put error response interceptor on redux-axios-middleware

I have a problem with https://github.com/svrcekmichal/redux-axios-middleware.
I want to set the interceptor response (error). But can't successfully set it up.
Here is my code:
function interceptorResponse({ dispatch, getState, getAction }, response) {
console.log(response);
}
export const client = axios.create({
baseURL: API_URL,
headers: {
Accept: 'application/json',
},
});
export const clientOptions = {
interceptors: {
request: [interceptorRequest],
response: [interceptorResponse],
},
};
the console.log(response) only respond if the response is 200. How can I set it to accept an error response?
I've tried set it like this
function interceptorResponse({ dispatch, getState, getAction }) {
return response => response.data, (error) => {
const meta = error.response.data.meta;
const { code, status } = meta;
console.log(meta);
};
}
but still never show anything.
Any soluion?
Here is an example usage with ES6 :
import axios from 'axios'
import axiosMiddleware from 'redux-axios-middleware'
const options = {
// not required, but use-full configuration option
returnRejectedPromiseOnError: true,
interceptors: {
request: [
({ getState, dispatch }, config) => {
// Request interception
return config
}
],
response: [
{
success: ({ dispatch }, response) => {
// Response interception
return response
},
error: ({ dispatch }, error) => {
// Response Error Interception
return Promise.reject(error)
}
}
]
}
}
export default axiosMiddleware(axios, options)
Note that the created middleware should be passed to createStore()

Resources